Skip to content

Commit 9746956

Browse files
committed
Merge remote-tracking branch 'upstream/develop' into chore/cleanup_contrib
* upstream/develop: (38 commits) Fix typo in function def CRC: pass block info as an optonal to send_block_response_impl Remove duplicate code when sending block responses fix: cargo check --tests warning address PR comments (6081) move CODEOWNERS and adjust requirements to automatically add multiple teams to reviews add index for processable_block in staging_blocks fix entry block-id/hash cache refactor perf: do not read whole snapshot for ancestor check in find_new_block_arrivals remove release build arg build all binaries in core build workflow crc: remove chrono dependency, #5918 Add missing import for SUPPORTED_SIGNER_PROTOCOL_VERSION crc: remove system time utility functions, #5918 crc: fix record_signer_agreement_capitulation_latency documentation, #5918 fix: mock miner should continue mining throughout tenure Remove testing assert from debugging Remove use of macro Add deserializer for custom blockstack op fields and make sure backwards compatibility satisfied for TransactionEventPayload CRC: typo in unreachable message ...
2 parents 7b22885 + e45867c commit 9746956

File tree

37 files changed

+1440
-437
lines changed

37 files changed

+1440
-437
lines changed

.github/CODEOWNERS

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# These owners will be the default owners for everything in
2+
# the repo. Unless a later match takes precedence,
3+
#
4+
# require both blockchain-team-codeowners and blockchain-team to review all PR's not specifically matched below
5+
* @stacks-network/blockchain-team-codeowners @stacks-network/blockchain-team
6+
7+
8+
# Signer code
9+
# require both blockchain-team-codeowners and blockchain-team-signer to review PR's for the signer folder(s)
10+
libsigner/**/*.rs @stacks-network/blockchain-team-codeowners @stacks-network/blockchain-team-signer
11+
stacks-signer/**/*.rs @stacks-network/blockchain-team-codeowners @stacks-network/blockchain-team-signer
12+
13+
# CI workflows
14+
# require both blockchain-team and blockchain-team-ci teams to review PR's modifying CI workflows
15+
/.github/workflows/ @stacks-network/blockchain-team @stacks-network/blockchain-team-ci
16+
/.github/actions/ @stacks-network/blockchain-team @stacks-network/blockchain-team-ci

.github/workflows/core-build-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ jobs:
2424
- name: Build the binaries
2525
id: build
2626
run: |
27-
cargo build --bin stacks-inspect
27+
cargo build
2828
- name: Dump constants JSON
2929
id: consts-dump
3030
run: cargo run --bin stacks-inspect -- dump-consts | tee out.json

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,21 @@ and this project adheres to the versioning scheme outlined in the [README.md](RE
99

1010
### Added
1111

12+
- Added field `vm_error` to EventObserver transaction outputs
1213
- Added new `ValidateRejectCode` values to the `/v3/block_proposal` endpoint
1314
- Added `StateMachineUpdateContent::V1` to support a vector of `StacksTransaction` expected to be replayed in subsequent Stacks blocks
15+
- Include a reason string in the transaction receipt when a transaction is rolled back due to a post-condition. This should help users in understanding what went wrong.
1416

1517
### Changed
1618

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

23+
### Fixed
24+
25+
- Fix regression in mock-mining, allowing the mock miner to continue mining blocks throughout a tenure instead of failing after mining the tenure change block.
26+
2127
## [3.1.0.0.8]
2228

2329
### Added

CODEOWNERS

Lines changed: 0 additions & 20 deletions
This file was deleted.

clarity/src/vm/clarity.rs

Lines changed: 49 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,30 @@ pub enum Error {
2020
Interpreter(InterpreterError),
2121
BadTransaction(String),
2222
CostError(ExecutionCost, ExecutionCost),
23-
AbortedByCallback(Option<Value>, AssetMap, Vec<StacksTransactionEvent>),
23+
AbortedByCallback {
24+
/// What the output value of the transaction would have been.
25+
/// This will be a Some for contract-calls, and None for contract initialization txs.
26+
output: Option<Value>,
27+
/// The asset map which was evaluated by the abort callback
28+
assets_modified: AssetMap,
29+
/// The events from the transaction processing
30+
tx_events: Vec<StacksTransactionEvent>,
31+
/// A human-readable explanation for aborting the transaction
32+
reason: String,
33+
},
2434
}
2535

2636
impl fmt::Display for Error {
2737
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
28-
match *self {
38+
match self {
2939
Error::CostError(ref a, ref b) => {
30-
write!(f, "Cost Error: {} cost exceeded budget of {} cost", a, b)
40+
write!(f, "Cost Error: {a} cost exceeded budget of {b} cost")
3141
}
3242
Error::Analysis(ref e) => fmt::Display::fmt(e, f),
3343
Error::Parse(ref e) => fmt::Display::fmt(e, f),
34-
Error::AbortedByCallback(..) => write!(f, "Post condition aborted transaction"),
44+
Error::AbortedByCallback { reason, .. } => {
45+
write!(f, "Post condition aborted transaction: {reason}")
46+
}
3547
Error::Interpreter(ref e) => fmt::Display::fmt(e, f),
3648
Error::BadTransaction(ref s) => fmt::Display::fmt(s, f),
3749
}
@@ -42,7 +54,7 @@ impl std::error::Error for Error {
4254
fn cause(&self) -> Option<&dyn std::error::Error> {
4355
match *self {
4456
Error::CostError(ref _a, ref _b) => None,
45-
Error::AbortedByCallback(..) => None,
57+
Error::AbortedByCallback { .. } => None,
4658
Error::Analysis(ref e) => Some(e),
4759
Error::Parse(ref e) => Some(e),
4860
Error::Interpreter(ref e) => Some(e),
@@ -168,16 +180,17 @@ pub trait TransactionConnection: ClarityConnection {
168180
/// * the asset changes during `to_do` in an `AssetMap`
169181
/// * the Stacks events during the transaction
170182
///
171-
/// and a `bool` value which is `true` if the `abort_call_back` caused the changes to abort.
183+
/// and an optional string value which is the result of `abort_call_back`,
184+
/// containing a human-readable reason for aborting the transaction.
172185
///
173186
/// If `to_do` returns an `Err` variant, then the changes are aborted.
174187
fn with_abort_callback<F, A, R, E>(
175188
&mut self,
176189
to_do: F,
177190
abort_call_back: A,
178-
) -> Result<(R, AssetMap, Vec<StacksTransactionEvent>, bool), E>
191+
) -> Result<(R, AssetMap, Vec<StacksTransactionEvent>, Option<String>), E>
179192
where
180-
A: FnOnce(&AssetMap, &mut ClarityDatabase) -> bool,
193+
A: FnOnce(&AssetMap, &mut ClarityDatabase) -> Option<String>,
181194
F: FnOnce(&mut OwnedEnvironment) -> Result<(R, AssetMap, Vec<StacksTransactionEvent>), E>,
182195
E: From<InterpreterError>;
183196

@@ -283,16 +296,16 @@ pub trait TransactionConnection: ClarityConnection {
283296
.stx_transfer(from, to, amount, memo)
284297
.map_err(Error::from)
285298
},
286-
|_, _| false,
299+
|_, _| None,
287300
)
288301
.map(|(value, assets, events, _)| (value, assets, events))
289302
}
290303

291304
/// Execute a contract call in the current block.
292-
/// If an error occurs while processing the transaction, its modifications will be rolled back.
293-
/// abort_call_back is called with an AssetMap and a ClarityDatabase reference,
294-
/// if abort_call_back returns true, all modifications from this transaction will be rolled back.
295-
/// otherwise, they will be committed (though they may later be rolled back if the block itself is rolled back).
305+
/// If an error occurs while processing the transaction, its modifications will be rolled back.
306+
/// `abort_call_back` is called with an `AssetMap` and a `ClarityDatabase` reference,
307+
/// If `abort_call_back` returns `Some(reason)`, all modifications from this transaction will be rolled back.
308+
/// Otherwise, they will be committed (though they may later be rolled back if the block itself is rolled back).
296309
#[allow(clippy::too_many_arguments)]
297310
fn run_contract_call<F>(
298311
&mut self,
@@ -305,7 +318,7 @@ pub trait TransactionConnection: ClarityConnection {
305318
max_execution_time: Option<std::time::Duration>,
306319
) -> Result<(Value, AssetMap, Vec<StacksTransactionEvent>), Error>
307320
where
308-
F: FnOnce(&AssetMap, &mut ClarityDatabase) -> bool,
321+
F: FnOnce(&AssetMap, &mut ClarityDatabase) -> Option<String>,
309322
{
310323
let expr_args: Vec<_> = args
311324
.iter()
@@ -331,20 +344,25 @@ pub trait TransactionConnection: ClarityConnection {
331344
},
332345
abort_call_back,
333346
)
334-
.and_then(|(value, assets, events, aborted)| {
335-
if aborted {
336-
Err(Error::AbortedByCallback(Some(value), assets, events))
347+
.and_then(|(value, assets_modified, tx_events, reason)| {
348+
if let Some(reason) = reason {
349+
Err(Error::AbortedByCallback {
350+
output: Some(value),
351+
assets_modified,
352+
tx_events,
353+
reason,
354+
})
337355
} else {
338-
Ok((value, assets, events))
356+
Ok((value, assets_modified, tx_events))
339357
}
340358
})
341359
}
342360

343361
/// Initialize a contract in the current block.
344362
/// If an error occurs while processing the initialization, it's modifications will be rolled back.
345-
/// abort_call_back is called with an AssetMap and a ClarityDatabase reference,
346-
/// if abort_call_back returns true, all modifications from this transaction will be rolled back.
347-
/// otherwise, they will be committed (though they may later be rolled back if the block itself is rolled back).
363+
/// `abort_call_back` is called with an `AssetMap` and a `ClarityDatabase` reference,
364+
/// If `abort_call_back` returns `Some(reason)`, all modifications from this transaction will be rolled back.
365+
/// Otherwise, they will be committed (though they may later be rolled back if the block itself is rolled back).
348366
#[allow(clippy::too_many_arguments)]
349367
fn initialize_smart_contract<F>(
350368
&mut self,
@@ -357,9 +375,9 @@ pub trait TransactionConnection: ClarityConnection {
357375
max_execution_time: Option<std::time::Duration>,
358376
) -> Result<(AssetMap, Vec<StacksTransactionEvent>), Error>
359377
where
360-
F: FnOnce(&AssetMap, &mut ClarityDatabase) -> bool,
378+
F: FnOnce(&AssetMap, &mut ClarityDatabase) -> Option<String>,
361379
{
362-
let (_, asset_map, events, aborted) = self.with_abort_callback(
380+
let (_, assets_modified, tx_events, reason) = self.with_abort_callback(
363381
|vm_env| {
364382
if let Some(max_execution_time_duration) = max_execution_time {
365383
vm_env
@@ -378,10 +396,15 @@ pub trait TransactionConnection: ClarityConnection {
378396
},
379397
abort_call_back,
380398
)?;
381-
if aborted {
382-
Err(Error::AbortedByCallback(None, asset_map, events))
399+
if let Some(reason) = reason {
400+
Err(Error::AbortedByCallback {
401+
output: None,
402+
assets_modified,
403+
tx_events,
404+
reason,
405+
})
383406
} else {
384-
Ok((asset_map, events))
407+
Ok((assets_modified, tx_events))
385408
}
386409
}
387410
}

stacks-signer/src/monitoring/mod.rs

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,21 @@ SignerAgreementStateChangeReason {
3333
InactiveMiner("inactive_miner"),
3434
/// Signer agreement protocol version has been upgraded
3535
ProtocolUpgrade("protocol_upgrade"),
36+
/// An update related to the Miner view
37+
MinerViewUpdate("miner_view_update"),
38+
/// A specific Miner View update related to the parent tenure
39+
MinerParentTenureUpdate("miner_parent_tenure_update"),
40+
});
41+
42+
define_named_enum!(
43+
/// Represent different conflict types on signer agreement protocol
44+
SignerAgreementStateConflict {
45+
/// Waiting for burn block propagation to be aligned with the signer set
46+
BurnBlockDelay("burn_block_delay"),
47+
/// Waiting for stacks block propagation to be aligned with the signer set
48+
StacksBlockDelay("stacks_block_delay"),
49+
/// No agreement on miner view with the signer set
50+
MinerView("miner_view"),
3651
});
3752

3853
/// Actions for updating metrics
@@ -44,7 +59,7 @@ pub mod actions {
4459

4560
use crate::config::GlobalConfig;
4661
use crate::monitoring::prometheus::*;
47-
use crate::monitoring::SignerAgreementStateChangeReason;
62+
use crate::monitoring::{SignerAgreementStateChangeReason, SignerAgreementStateConflict};
4863
use crate::v0::signer_state::LocalStateMachine;
4964

5065
/// Update stacks tip height gauge
@@ -134,6 +149,21 @@ pub mod actions {
134149
.inc();
135150
}
136151

152+
/// Increment signer agreement state conflict counter
153+
pub fn increment_signer_agreement_state_conflict(conflict: SignerAgreementStateConflict) {
154+
let label_value = conflict.get_name();
155+
SIGNER_AGREEMENT_STATE_CONFLICTS
156+
.with_label_values(&[&label_value])
157+
.inc();
158+
}
159+
160+
/// Record the time (seconds) taken for a signer to agree with the signer set
161+
pub fn record_signer_agreement_capitulation_latency(latency_s: u64) {
162+
SIGNER_AGREEMENT_CAPITULATION_LATENCIES_HISTOGRAM
163+
.with_label_values(&[])
164+
.observe(latency_s as f64);
165+
}
166+
137167
/// Start serving monitoring metrics.
138168
/// This will only serve the metrics if the `monitoring_prom` feature is enabled.
139169
pub fn start_serving_monitoring_metrics(config: GlobalConfig) -> Result<(), String> {
@@ -157,7 +187,7 @@ pub mod actions {
157187
use blockstack_lib::chainstate::nakamoto::NakamotoBlock;
158188
use stacks_common::info;
159189

160-
use crate::monitoring::SignerAgreementStateChangeReason;
190+
use crate::monitoring::{SignerAgreementStateChangeReason, SignerAgreementStateConflict};
161191
use crate::v0::signer_state::LocalStateMachine;
162192
use crate::GlobalConfig;
163193

@@ -212,6 +242,12 @@ pub mod actions {
212242
) {
213243
}
214244

245+
/// Increment signer agreement state conflict counter
246+
pub fn increment_signer_agreement_state_conflict(_conflict: SignerAgreementStateConflict) {}
247+
248+
/// Record the time (seconds) taken for a signer to agree with the signer set
249+
pub fn record_signer_agreement_capitulation_latency(_latency_s: u64) {}
250+
215251
/// Start serving monitoring metrics.
216252
/// This will only serve the metrics if the `monitoring_prom` feature is enabled.
217253
pub fn start_serving_monitoring_metrics(config: GlobalConfig) -> Result<(), String> {

stacks-signer/src/monitoring/prometheus.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,22 @@ lazy_static! {
8181

8282
pub static ref SIGNER_AGREEMENT_STATE_CHANGE_REASONS: IntCounterVec = register_int_counter_vec!(
8383
"stacks_signer_agreement_state_change_reasons",
84-
"The number of state machine changes in signer agreement protocol. `reason` can be one of: 'burn_block_arrival', 'stacks_block_arrival', 'inactive_miner', 'protocol_upgrade'",
84+
"The number of state machine changes in signer agreement protocol. `reason` can be one of: 'burn_block_arrival', 'stacks_block_arrival', 'inactive_miner', 'protocol_upgrade', 'miner_view_update', 'miner_parent_tenure_update'",
8585
&["reason"]
8686
).unwrap();
8787

88+
pub static ref SIGNER_AGREEMENT_STATE_CONFLICTS: IntCounterVec = register_int_counter_vec!(
89+
"stacks_signer_agreement_state_conflicts",
90+
"The number of state machine conflicts in signer agreement protocol. `conflict` can be one of: 'burn_block_delay', 'stacks_block_delay', 'miner_view'",
91+
&["conflict"]
92+
).unwrap();
93+
94+
pub static ref SIGNER_AGREEMENT_CAPITULATION_LATENCIES_HISTOGRAM: HistogramVec = register_histogram_vec!(histogram_opts!(
95+
"stacks_signer_agreement_capitulation_latencies_histogram",
96+
"Measuring the time (in seconds) for the signer to agree (capitulate) with the signer set",
97+
vec![0.0, 1.0, 3.0, 5.0, 10.0, 20.0, 30.0, 60.0, 120.0]
98+
), &[]).unwrap();
99+
88100
pub static ref SIGNER_LOCAL_STATE_MACHINE: Mutex<Option<LocalStateMachine>> = Mutex::new(None);
89101
}
90102

0 commit comments

Comments
 (0)