• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

stacks-network / stacks-core / 26250451051-1

21 May 2026 08:11PM UTC coverage: 85.585% (-0.1%) from 85.712%
26250451051-1

Pull #7215

github

ec9d4c
web-flow
Merge 9487bf852 into af1280aac
Pull Request #7215: Chore: fix flake in non_blocking_minority_configured_to_favour_...

188844 of 220651 relevant lines covered (85.58%)

18975267.44 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

89.85
/stackslib/src/monitoring/mod.rs
1
// Copyright (C) 2013-2020 Blockstack PBC, a public benefit corporation
2
// Copyright (C) 2020 Stacks Open Internet Foundation
3
//
4
// This program is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// This program is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
16

17
use std::error::Error;
18
use std::path::PathBuf;
19
use std::{fmt, fs};
20

21
use clarity::vm::costs::ExecutionCost;
22
use rusqlite::{OpenFlags, OptionalExtension};
23
use stacks_common::types::sqlite::NO_PARAMS;
24
use stacks_common::util::uint::{Uint256, Uint512};
25

26
use crate::burnchains::{BurnchainSigner, Txid};
27
use crate::net::httpcore::StacksHttpRequest;
28
use crate::net::rpc::ConversationHttp;
29
use crate::net::Error as net_error;
30
use crate::util_lib::db::{sqlite_open, DBConn, Error as DatabaseError};
31

32
#[cfg(feature = "monitoring_prom")]
33
mod prometheus;
34

35
#[cfg(feature = "monitoring_prom")]
36
lazy_static::lazy_static! {
37
    static ref GLOBAL_BURNCHAIN_SIGNER: std::sync::Mutex<Option<BurnchainSigner>> = std::sync::Mutex::new(None);
38
}
39

40
pub fn increment_rpc_calls_counter() {
6,597,584✔
41
    #[cfg(feature = "monitoring_prom")]
42
    prometheus::RPC_CALL_COUNTER.inc();
6,597,584✔
43
}
6,597,584✔
44

45
#[allow(unused_mut)]
46
pub fn instrument_http_request_handler<F, R>(
6,597,584✔
47
    conv_http: &mut ConversationHttp,
6,597,584✔
48
    #[allow(unused_mut)] mut req: StacksHttpRequest,
6,597,584✔
49
    handler: F,
6,597,584✔
50
) -> Result<R, net_error>
6,597,584✔
51
where
6,597,584✔
52
    F: FnOnce(&mut ConversationHttp, StacksHttpRequest) -> Result<R, net_error>,
6,597,584✔
53
{
54
    #[cfg(feature = "monitoring_prom")]
55
    increment_rpc_calls_counter();
6,597,584✔
56

57
    #[cfg(feature = "monitoring_prom")]
58
    let timer = prometheus::new_rpc_call_timer(conv_http.metrics_identifier(&mut req));
6,597,584✔
59

60
    let res = handler(conv_http, req);
6,597,584✔
61

62
    #[cfg(feature = "monitoring_prom")]
63
    timer.stop_and_record();
6,597,584✔
64

65
    res
6,597,584✔
66
}
6,597,584✔
67

68
pub fn increment_stx_blocks_received_counter() {
17,352✔
69
    #[cfg(feature = "monitoring_prom")]
70
    prometheus::STX_BLOCKS_RECEIVED_COUNTER.inc();
17,352✔
71
}
17,352✔
72

73
pub fn increment_stx_micro_blocks_received_counter() {
×
74
    #[cfg(feature = "monitoring_prom")]
75
    prometheus::STX_MICRO_BLOCKS_RECEIVED_COUNTER.inc();
×
76
}
×
77

78
pub fn increment_stx_blocks_served_counter() {
×
79
    #[cfg(feature = "monitoring_prom")]
80
    prometheus::STX_BLOCKS_SERVED_COUNTER.inc();
×
81
}
×
82

83
pub fn increment_stx_micro_blocks_served_counter() {
×
84
    #[cfg(feature = "monitoring_prom")]
85
    prometheus::STX_MICRO_BLOCKS_SERVED_COUNTER.inc();
×
86
}
×
87

88
pub fn increment_stx_confirmed_micro_blocks_served_counter() {
×
89
    #[cfg(feature = "monitoring_prom")]
90
    prometheus::STX_CONFIRMED_MICRO_BLOCKS_SERVED_COUNTER.inc();
×
91
}
×
92

93
pub fn increment_txs_received_counter() {
4,509✔
94
    #[cfg(feature = "monitoring_prom")]
95
    prometheus::TXS_RECEIVED_COUNTER.inc();
4,509✔
96
}
4,509✔
97

98
pub fn increment_btc_blocks_received_counter() {
4,049,316✔
99
    #[cfg(feature = "monitoring_prom")]
100
    prometheus::BTC_BLOCKS_RECEIVED_COUNTER.inc();
4,049,316✔
101
}
4,049,316✔
102

103
/// Log `execution_cost` as a ratio of `block_limit`.
104
#[allow(unused_variables)]
105
pub fn set_last_execution_cost_observed(
143,761✔
106
    execution_cost: &ExecutionCost,
143,761✔
107
    block_limit: &ExecutionCost,
143,761✔
108
) {
143,761✔
109
    #[cfg(feature = "monitoring_prom")]
110
    {
143,761✔
111
        prometheus::LAST_BLOCK_READ_COUNT
143,761✔
112
            .set(execution_cost.read_count as f64 / block_limit.read_count as f64);
143,761✔
113
        prometheus::LAST_BLOCK_WRITE_COUNT
143,761✔
114
            .set(execution_cost.write_count as f64 / block_limit.read_count as f64);
143,761✔
115
        prometheus::LAST_BLOCK_READ_LENGTH
143,761✔
116
            .set(execution_cost.read_length as f64 / block_limit.read_length as f64);
143,761✔
117
        prometheus::LAST_BLOCK_WRITE_LENGTH
143,761✔
118
            .set(execution_cost.write_length as f64 / block_limit.write_length as f64);
143,761✔
119
        prometheus::LAST_BLOCK_RUNTIME
143,761✔
120
            .set(execution_cost.runtime as f64 / block_limit.runtime as f64);
143,761✔
121
    }
143,761✔
122
}
143,761✔
123

124
/// Log the number of transactions in the latest block.
125
#[allow(unused_variables)]
126
pub fn set_last_block_transaction_count(transactions_in_block: u64) {
143,761✔
127
    // Saturating cast from u64 to i64
128
    #[cfg(feature = "monitoring_prom")]
129
    prometheus::LAST_BLOCK_TRANSACTION_COUNT
143,761✔
130
        .set(i64::try_from(transactions_in_block).unwrap_or(i64::MAX));
143,761✔
131
}
143,761✔
132

133
/// Log `execution_cost` as a ratio of `block_limit`.
134
#[allow(unused_variables)]
135
pub fn set_last_mined_execution_cost_observed(
254,217✔
136
    execution_cost: &ExecutionCost,
254,217✔
137
    block_limit: &ExecutionCost,
254,217✔
138
) {
254,217✔
139
    #[cfg(feature = "monitoring_prom")]
140
    {
254,217✔
141
        prometheus::LAST_MINED_BLOCK_READ_COUNT
254,217✔
142
            .set(execution_cost.read_count as f64 / block_limit.read_count as f64);
254,217✔
143
        prometheus::LAST_MINED_BLOCK_WRITE_COUNT
254,217✔
144
            .set(execution_cost.write_count as f64 / block_limit.read_count as f64);
254,217✔
145
        prometheus::LAST_MINED_BLOCK_READ_LENGTH
254,217✔
146
            .set(execution_cost.read_length as f64 / block_limit.read_length as f64);
254,217✔
147
        prometheus::LAST_MINED_BLOCK_WRITE_LENGTH
254,217✔
148
            .set(execution_cost.write_length as f64 / block_limit.write_length as f64);
254,217✔
149
        prometheus::LAST_MINED_BLOCK_RUNTIME
254,217✔
150
            .set(execution_cost.runtime as f64 / block_limit.runtime as f64);
254,217✔
151
    }
254,217✔
152
}
254,217✔
153

154
/// Log the number of transactions in the latest block.
155
#[allow(unused_variables)]
156
pub fn set_last_mined_block_transaction_count(transactions_in_block: u64) {
278,121✔
157
    // Saturating cast from u64 to i64
158
    #[cfg(feature = "monitoring_prom")]
159
    prometheus::LAST_MINED_BLOCK_TRANSACTION_COUNT
278,121✔
160
        .set(i64::try_from(transactions_in_block).unwrap_or(i64::MAX));
278,121✔
161
}
278,121✔
162

163
pub fn increment_btc_ops_sent_counter() {
78,399✔
164
    #[cfg(feature = "monitoring_prom")]
165
    prometheus::BTC_OPS_SENT_COUNTER.inc();
78,399✔
166
}
78,399✔
167

168
pub fn increment_stx_blocks_processed_counter() {
137,350✔
169
    #[cfg(feature = "monitoring_prom")]
170
    prometheus::STX_BLOCKS_PROCESSED_COUNTER.inc();
137,350✔
171
}
137,350✔
172

173
pub fn increment_stx_blocks_mined_counter() {
87,786✔
174
    #[cfg(feature = "monitoring_prom")]
175
    prometheus::STX_BLOCKS_MINED_COUNTER.inc();
87,786✔
176
}
87,786✔
177

178
pub fn increment_warning_emitted_counter() {
×
179
    #[cfg(feature = "monitoring_prom")]
180
    prometheus::WARNING_EMITTED_COUNTER.inc();
×
181
}
×
182

183
pub fn increment_errors_emitted_counter() {
×
184
    #[cfg(feature = "monitoring_prom")]
185
    prometheus::ERRORS_EMITTED_COUNTER.inc();
×
186
}
×
187

188
pub fn increment_unreachable_errors_counter(_error_type: &str) {
10✔
189
    #[cfg(feature = "monitoring_prom")]
190
    prometheus::UNREACHABLE_ERRORS_COUNTER
10✔
191
        .with_label_values(&[_error_type])
10✔
192
        .inc();
10✔
193
}
10✔
194

195
fn txid_tracking_db(chainstate_root_path: &str) -> Result<DBConn, DatabaseError> {
913,469✔
196
    let mut path = PathBuf::from(chainstate_root_path);
913,469✔
197

198
    path.push("tx_tracking.sqlite");
913,469✔
199
    let db_path = path.to_str().ok_or_else(|| DatabaseError::ParseError)?;
913,469✔
200

201
    let mut create_flag = false;
913,469✔
202
    let open_flags = if fs::metadata(&db_path).is_err() {
913,469✔
203
        // need to create
204
        create_flag = true;
2,959✔
205
        OpenFlags::SQLITE_OPEN_READ_WRITE | OpenFlags::SQLITE_OPEN_CREATE
2,959✔
206
    } else {
207
        // can just open
208
        OpenFlags::SQLITE_OPEN_READ_WRITE
910,510✔
209
    };
210

211
    let conn = sqlite_open(&db_path, open_flags, false)?;
913,469✔
212

213
    if create_flag {
913,469✔
214
        conn.execute(
2,959✔
215
            "CREATE TABLE processed_txids (txid TEXT NOT NULL PRIMARY KEY)",
2,959✔
216
            NO_PARAMS,
217
        )?;
×
218
    }
910,510✔
219

220
    Ok(conn)
913,469✔
221
}
913,469✔
222

223
fn txid_tracking_db_contains(conn: &DBConn, txid: &Txid) -> Result<bool, DatabaseError> {
684,112✔
224
    let contains = conn
684,112✔
225
        .query_row(
684,112✔
226
            "SELECT 1 FROM processed_txids WHERE txid = ?",
684,112✔
227
            &[txid],
684,112✔
228
            |_row| Ok(true),
229
        )
230
        .optional()?
684,112✔
231
        .is_some();
684,112✔
232
    Ok(contains)
684,112✔
233
}
684,112✔
234

235
#[allow(unused_variables)]
236
pub fn mempool_accepted(txid: &Txid, chainstate_root_path: &str) -> Result<(), DatabaseError> {
39,263✔
237
    #[cfg(feature = "monitoring_prom")]
238
    {
239
        let tracking_db = txid_tracking_db(chainstate_root_path)?;
39,263✔
240

241
        if txid_tracking_db_contains(&tracking_db, txid)? {
39,263✔
242
            // processed by a previous block, do not track again
243
            return Ok(());
×
244
        }
39,263✔
245

246
        prometheus::MEMPOOL_OUTSTANDING_TXS.inc();
39,263✔
247
    }
248

249
    Ok(())
39,263✔
250
}
39,263✔
251

252
#[allow(unused_variables)]
253
pub fn log_transaction_processed(
899,879✔
254
    txid: &Txid,
899,879✔
255
    chainstate_root_path: &str,
899,879✔
256
) -> Result<(), DatabaseError> {
899,879✔
257
    #[cfg(feature = "monitoring_prom")]
258
    {
259
        let mempool_db_path = crate::core::MemPoolDB::db_path(chainstate_root_path)?;
899,879✔
260
        let mempool_conn = sqlite_open(&mempool_db_path, OpenFlags::SQLITE_OPEN_READ_ONLY, false)?;
899,879✔
261
        let tracking_db = txid_tracking_db(chainstate_root_path)?;
874,206✔
262

263
        let tx = match crate::core::MemPoolDB::get_tx(&mempool_conn, txid)? {
874,206✔
264
            Some(tx) => tx,
644,849✔
265
            None => {
266
                debug!("Could not log transaction receive to process time, txid not found in mempool"; "txid" => %txid);
229,357✔
267
                return Ok(());
229,357✔
268
            }
269
        };
270

271
        if txid_tracking_db_contains(&tracking_db, txid)? {
644,849✔
272
            // processed by a previous block, do not track again
273
            return Ok(());
×
274
        }
644,849✔
275

276
        let mempool_accept_time = tx.metadata.accept_time;
644,849✔
277
        let time_now = clarity::util::get_epoch_time_secs();
644,849✔
278

279
        let time_to_process = time_now - mempool_accept_time;
644,849✔
280

281
        prometheus::MEMPOOL_OUTSTANDING_TXS.dec();
644,849✔
282
        prometheus::MEMPOOL_TX_CONFIRM_TIME.observe(time_to_process as f64);
644,849✔
283
    }
284
    Ok(())
644,849✔
285
}
899,879✔
286

287
#[allow(unused_variables)]
288
pub fn update_active_miners_count_gauge(value: i64) {
603,909✔
289
    #[cfg(feature = "monitoring_prom")]
290
    prometheus::ACTIVE_MINERS_COUNT_GAUGE.set(value);
603,909✔
291
}
603,909✔
292

293
#[allow(unused_variables)]
294
pub fn update_stacks_tip_height(value: i64) {
8,580,983✔
295
    #[cfg(feature = "monitoring_prom")]
296
    prometheus::STACKS_TIP_HEIGHT_GAUGE.set(value);
8,580,983✔
297
}
8,580,983✔
298

299
#[allow(unused_variables)]
300
pub fn update_burnchain_height(value: i64) {
119,808✔
301
    #[cfg(feature = "monitoring_prom")]
302
    prometheus::BURNCHAIN_HEIGHT_GAUGE.set(value);
119,808✔
303
}
119,808✔
304

305
#[allow(unused_variables)]
306
pub fn update_inbound_neighbors(value: i64) {
10,385,364✔
307
    #[cfg(feature = "monitoring_prom")]
308
    prometheus::INBOUND_NEIGHBORS_GAUGE.set(value);
10,385,364✔
309
}
10,385,364✔
310

311
#[allow(unused_variables)]
312
pub fn update_outbound_neighbors(value: i64) {
10,385,364✔
313
    #[cfg(feature = "monitoring_prom")]
314
    prometheus::OUTBOUND_NEIGHBORS_GAUGE.set(value);
10,385,364✔
315
}
10,385,364✔
316

317
#[allow(unused_variables)]
318
pub fn update_inbound_bandwidth(value: i64) {
27,162,871✔
319
    #[cfg(feature = "monitoring_prom")]
320
    prometheus::INBOUND_BANDWIDTH_GAUGE.add(value);
27,162,871✔
321
}
27,162,871✔
322

323
#[allow(unused_variables)]
324
pub fn update_outbound_bandwidth(value: i64) {
95,738,811✔
325
    #[cfg(feature = "monitoring_prom")]
326
    prometheus::OUTBOUND_BANDWIDTH_GAUGE.add(value);
95,738,811✔
327
}
95,738,811✔
328

329
#[allow(unused_variables)]
330
pub fn update_inbound_rpc_bandwidth(value: i64) {
20,014,010✔
331
    #[cfg(feature = "monitoring_prom")]
332
    prometheus::INBOUND_RPC_BANDWIDTH_GAUGE.add(value);
20,014,010✔
333
}
20,014,010✔
334

335
#[allow(unused_variables)]
336
pub fn update_outbound_rpc_bandwidth(value: i64) {
×
337
    #[cfg(feature = "monitoring_prom")]
338
    prometheus::OUTBOUND_RPC_BANDWIDTH_GAUGE.add(value);
×
339
}
×
340

341
#[allow(unused_variables)]
342
pub fn increment_msg_counter(name: String) {
1,515,764✔
343
    #[cfg(feature = "monitoring_prom")]
344
    prometheus::MSG_COUNTER_VEC
1,515,764✔
345
        .with_label_values(&[&name])
1,515,764✔
346
        .inc();
1,515,764✔
347
}
1,515,764✔
348

349
pub fn increment_stx_mempool_gc() {
2,153,982✔
350
    #[cfg(feature = "monitoring_prom")]
351
    prometheus::STX_MEMPOOL_GC.inc();
2,153,982✔
352
}
2,153,982✔
353

354
pub fn increment_contract_calls_processed() {
22,879✔
355
    #[cfg(feature = "monitoring_prom")]
356
    prometheus::CONTRACT_CALLS_PROCESSED_COUNT.inc();
22,879✔
357
}
22,879✔
358

359
/// Given a value (type uint256), return value/uint256::max() as an f64 value.
360
/// The precision of the percentage is determined by the input `precision_points`, which is capped
361
/// at a max of 15.
362
fn convert_uint256_to_f64_percentage(value: Uint256, precision_points: u32) -> f64 {
85,262✔
363
    let precision_points = precision_points.min(15);
85,262✔
364
    let base = 10;
85,262✔
365
    let multiplier = Uint512::from_u128(100 * u128::pow(base, precision_points));
85,262✔
366
    let intermediate_result = ((Uint512::from_uint256(&value) * multiplier)
85,262✔
367
        / Uint512::from_uint256(&Uint256::max()))
85,262✔
368
    .low_u64() as i64;
85,262✔
369
    let divisor = i64::pow(base as i64, precision_points);
85,262✔
370

371
    let result = intermediate_result as f64 / divisor as f64;
85,262✔
372
    result
85,262✔
373
}
85,262✔
374

375
#[cfg(test)]
376
macro_rules! assert_approx_eq {
377
    ($a: expr, $b: expr) => {{
378
        let (a, b) = (&$a, &$b);
379
        assert!(
380
            (*a - *b).abs() < 1.0e-6,
381
            "{} is not approximately equal to {}",
382
            *a,
383
            *b
384
        );
385
    }};
386
}
387

388
#[test]
389
pub fn test_convert_uint256_to_f64() {
1✔
390
    let original = ((Uint512::from_uint256(&Uint256::max()) * Uint512::from_u64(10))
1✔
391
        / Uint512::from_u64(100))
1✔
392
    .to_uint256();
1✔
393
    assert_approx_eq!(convert_uint256_to_f64_percentage(original, 7), 10_f64);
1✔
394

395
    let original = ((Uint512::from_uint256(&Uint256::max()) * Uint512::from_u64(122))
1✔
396
        / Uint512::from_u64(1000))
1✔
397
    .to_uint256();
1✔
398
    assert_approx_eq!(convert_uint256_to_f64_percentage(original, 7), 12.2);
1✔
399

400
    let original = ((Uint512::from_uint256(&Uint256::max()) * Uint512::from_u64(122345))
1✔
401
        / Uint512::from_u64(1000000))
1✔
402
    .to_uint256();
1✔
403
    assert_approx_eq!(convert_uint256_to_f64_percentage(original, 7), 12.2345);
1✔
404

405
    let original = ((Uint512::from_uint256(&Uint256::max()) * Uint512::from_u64(12234567))
1✔
406
        / Uint512::from_u64(100000000))
1✔
407
    .to_uint256();
1✔
408
    assert_approx_eq!(convert_uint256_to_f64_percentage(original, 7), 12.234567);
1✔
409

410
    let original = ((Uint512::from_uint256(&Uint256::max()) * Uint512::from_u64(12234567))
1✔
411
        / Uint512::from_u64(100000000))
1✔
412
    .to_uint256();
1✔
413
    assert_approx_eq!(convert_uint256_to_f64_percentage(original, 1000), 12.234567);
1✔
414
}
1✔
415

416
#[allow(unused_variables)]
417
pub fn update_computed_relative_miner_score(value: Uint256) {
85,257✔
418
    #[cfg(feature = "monitoring_prom")]
419
    {
85,257✔
420
        let percentage = convert_uint256_to_f64_percentage(value, 7);
85,257✔
421
        prometheus::COMPUTED_RELATIVE_MINER_SCORE.set(percentage);
85,257✔
422
    }
85,257✔
423
}
85,257✔
424

425
#[allow(unused_variables)]
426
pub fn update_computed_miner_commitment(value: u128) {
85,257✔
427
    #[cfg(feature = "monitoring_prom")]
428
    {
85,257✔
429
        let high_bits = (value >> 64) as u64;
85,257✔
430
        let low_bits = value as u64;
85,257✔
431
        prometheus::COMPUTED_MINER_COMMITMENT_HIGH.set(high_bits as i64);
85,257✔
432
        prometheus::COMPUTED_MINER_COMMITMENT_LOW.set(low_bits as i64);
85,257✔
433
    }
85,257✔
434
}
85,257✔
435

436
#[allow(unused_variables)]
437
pub fn update_miner_current_median_commitment(value: u128) {
85,257✔
438
    #[cfg(feature = "monitoring_prom")]
439
    {
85,257✔
440
        let high_bits = (value >> 64) as u64;
85,257✔
441
        let low_bits = value as u64;
85,257✔
442
        prometheus::MINER_CURRENT_MEDIAN_COMMITMENT_HIGH.set(high_bits as i64);
85,257✔
443
        prometheus::MINER_CURRENT_MEDIAN_COMMITMENT_LOW.set(low_bits as i64);
85,257✔
444
    }
85,257✔
445
}
85,257✔
446

447
/// Function sets the global variable `GLOBAL_BURNCHAIN_SIGNER`.
448
/// Fails if there are multiple attempts to set this variable.
449
#[allow(unused_variables)]
450
pub fn set_burnchain_signer(signer: BurnchainSigner) -> Result<(), SetGlobalBurnchainSignerError> {
4,698✔
451
    #[cfg(feature = "monitoring_prom")]
452
    {
453
        let mut signer_mutex = GLOBAL_BURNCHAIN_SIGNER.lock().unwrap();
4,698✔
454
        if signer_mutex.is_some() {
4,698✔
455
            return Err(SetGlobalBurnchainSignerError);
2,628✔
456
        }
2,070✔
457

458
        *signer_mutex = Some(signer);
2,070✔
459
    }
460
    Ok(())
2,070✔
461
}
4,698✔
462

463
#[allow(unreachable_code)]
464
pub fn get_burnchain_signer() -> Option<BurnchainSigner> {
624,572✔
465
    #[cfg(feature = "monitoring_prom")]
466
    {
467
        return GLOBAL_BURNCHAIN_SIGNER.lock().unwrap().clone();
624,572✔
468
    }
469
    None
470
}
624,572✔
471

472
define_named_enum!(MinerStopReason {
473
    NoTransactions("no_transactions"),
474
    Preempted("preempted"),
475
    LimitReached("limit_reached"),
476
    DeadlineReached("deadline_reached"),
477
});
478

479
// Increment the counter for the given miner stop reason.
480
#[allow(unused_variables)]
481
pub fn increment_miner_stop_reason(reason: MinerStopReason) {
364,133✔
482
    #[cfg(feature = "monitoring_prom")]
483
    prometheus::MINER_STOP_REASON_TOTAL
364,133✔
484
        .with_label_values(&[reason.get_name_str()])
364,133✔
485
        .inc();
364,133✔
486
}
364,133✔
487

488
#[derive(Debug)]
489
pub struct SetGlobalBurnchainSignerError;
490

491
impl fmt::Display for SetGlobalBurnchainSignerError {
492
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
×
493
        f.pad("A global default burnchain signer has already been set.")
×
494
    }
×
495
}
496

497
impl Error for SetGlobalBurnchainSignerError {}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc