Skip to content

Commit 3d2949d

Browse files
committed
CRC: use lazyLock instead of OnceLock for static sync global variable
Signed-off-by: Jacinta Ferrant <[email protected]>
1 parent 767dd7e commit 3d2949d

File tree

2 files changed

+92
-110
lines changed

2 files changed

+92
-110
lines changed

stacks-common/src/types/mod.rs

Lines changed: 59 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use std::cell::LazyCell;
1818
use std::cmp::Ordering;
1919
use std::fmt;
2020
use std::ops::{Deref, DerefMut, Index, IndexMut};
21-
use std::sync::OnceLock;
21+
use std::sync::LazyLock;
2222

2323
#[cfg(feature = "canonical")]
2424
pub mod sqlite;
@@ -136,75 +136,60 @@ pub struct CoinbaseInterval {
136136
// The above is for mainnet, which has a burnchain year of 52596 blocks and starts at burnchain height 666050.
137137

138138
/// Mainnet coinbase intervals, as of SIP-029
139-
// This static value is lazily initialized using `OnceLock` to avoid unnecessary
140-
// computation at program startup while ensuring thread safety and one-time initialization.
141-
// The intervals define the emission schedule for mainnet and are validated at runtime.
142-
pub static COINBASE_INTERVALS_MAINNET: OnceLock<[CoinbaseInterval; 5]> = OnceLock::new();
143-
144-
pub fn get_coinbase_intervals_mainnet() -> &'static [CoinbaseInterval; 5] {
145-
COINBASE_INTERVALS_MAINNET.get_or_init(|| {
146-
let emissions_schedule = [
147-
CoinbaseInterval {
148-
coinbase: 1_000 * u128::from(MICROSTACKS_PER_STACKS),
149-
effective_start_height: 0,
150-
},
151-
CoinbaseInterval {
152-
coinbase: 500 * u128::from(MICROSTACKS_PER_STACKS),
153-
effective_start_height: 278_950,
154-
},
155-
CoinbaseInterval {
156-
coinbase: 250 * u128::from(MICROSTACKS_PER_STACKS),
157-
effective_start_height: 383_950,
158-
},
159-
CoinbaseInterval {
160-
coinbase: 125 * u128::from(MICROSTACKS_PER_STACKS),
161-
effective_start_height: 593_950,
162-
},
163-
CoinbaseInterval {
164-
coinbase: (625 * u128::from(MICROSTACKS_PER_STACKS)) / 10,
165-
effective_start_height: 803_950,
166-
},
167-
];
168-
assert!(CoinbaseInterval::check_order(&emissions_schedule));
169-
emissions_schedule
170-
})
171-
}
172-
173-
/// Testnet coinbase intervals as defined by SIP-029.
174-
///
175-
/// This static value is lazily initialized using `OnceLock` to avoid unnecessary
176-
/// computation at program startup while ensuring thread safety and one-time initialization.
177-
/// The intervals define the emission schedule for testnet and are validated at runtime.
178-
pub static COINBASE_INTERVALS_TESTNET: OnceLock<[CoinbaseInterval; 5]> = OnceLock::new();
179-
180-
pub fn get_coinbase_intervals_testnet() -> &'static [CoinbaseInterval; 5] {
181-
COINBASE_INTERVALS_TESTNET.get_or_init(|| {
182-
let emissions_schedule = [
183-
CoinbaseInterval {
184-
coinbase: 1_000 * u128::from(MICROSTACKS_PER_STACKS),
185-
effective_start_height: 0,
186-
},
187-
CoinbaseInterval {
188-
coinbase: 500 * u128::from(MICROSTACKS_PER_STACKS),
189-
effective_start_height: 77_777,
190-
},
191-
CoinbaseInterval {
192-
coinbase: 250 * u128::from(MICROSTACKS_PER_STACKS),
193-
effective_start_height: 77_777 * 7,
194-
},
195-
CoinbaseInterval {
196-
coinbase: 125 * u128::from(MICROSTACKS_PER_STACKS),
197-
effective_start_height: 77_777 * 14,
198-
},
199-
CoinbaseInterval {
200-
coinbase: (625 * u128::from(MICROSTACKS_PER_STACKS)) / 10,
201-
effective_start_height: 77_777 * 21,
202-
},
203-
];
204-
assert!(CoinbaseInterval::check_order(&emissions_schedule));
205-
emissions_schedule
206-
})
207-
}
139+
pub static COINBASE_INTERVALS_MAINNET: LazyLock<[CoinbaseInterval; 5]> = LazyLock::new(|| {
140+
let emissions_schedule = [
141+
CoinbaseInterval {
142+
coinbase: 1_000 * u128::from(MICROSTACKS_PER_STACKS),
143+
effective_start_height: 0,
144+
},
145+
CoinbaseInterval {
146+
coinbase: 500 * u128::from(MICROSTACKS_PER_STACKS),
147+
effective_start_height: 278_950,
148+
},
149+
CoinbaseInterval {
150+
coinbase: 250 * u128::from(MICROSTACKS_PER_STACKS),
151+
effective_start_height: 383_950,
152+
},
153+
CoinbaseInterval {
154+
coinbase: 125 * u128::from(MICROSTACKS_PER_STACKS),
155+
effective_start_height: 593_950,
156+
},
157+
CoinbaseInterval {
158+
coinbase: (625 * u128::from(MICROSTACKS_PER_STACKS)) / 10,
159+
effective_start_height: 803_950,
160+
},
161+
];
162+
assert!(CoinbaseInterval::check_order(&emissions_schedule));
163+
emissions_schedule
164+
});
165+
166+
/// Testnet coinbase intervals, as of SIP-029
167+
pub static COINBASE_INTERVALS_TESTNET: LazyLock<[CoinbaseInterval; 5]> = LazyLock::new(|| {
168+
let emissions_schedule = [
169+
CoinbaseInterval {
170+
coinbase: 1_000 * u128::from(MICROSTACKS_PER_STACKS),
171+
effective_start_height: 0,
172+
},
173+
CoinbaseInterval {
174+
coinbase: 500 * u128::from(MICROSTACKS_PER_STACKS),
175+
effective_start_height: 77_777,
176+
},
177+
CoinbaseInterval {
178+
coinbase: 250 * u128::from(MICROSTACKS_PER_STACKS),
179+
effective_start_height: 77_777 * 7,
180+
},
181+
CoinbaseInterval {
182+
coinbase: 125 * u128::from(MICROSTACKS_PER_STACKS),
183+
effective_start_height: 77_777 * 14,
184+
},
185+
CoinbaseInterval {
186+
coinbase: (625 * u128::from(MICROSTACKS_PER_STACKS)) / 10,
187+
effective_start_height: 77_777 * 21,
188+
},
189+
];
190+
assert!(CoinbaseInterval::check_order(&emissions_schedule));
191+
emissions_schedule
192+
});
208193

209194
/// Used for testing to substitute a coinbase schedule
210195
#[cfg(any(test, feature = "testing"))]
@@ -500,18 +485,18 @@ impl StacksEpochId {
500485
}
501486

502487
if mainnet {
503-
get_coinbase_intervals_mainnet().to_vec()
488+
COINBASE_INTERVALS_MAINNET.to_vec()
504489
} else {
505-
get_coinbase_intervals_testnet().to_vec()
490+
COINBASE_INTERVALS_TESTNET.to_vec()
506491
}
507492
}
508493

509494
#[cfg(not(any(test, feature = "testing")))]
510495
pub(crate) fn get_coinbase_intervals(mainnet: bool) -> Vec<CoinbaseInterval> {
511496
if mainnet {
512-
get_coinbase_intervals_mainnet().to_vec()
497+
COINBASE_INTERVALS_MAINNET.to_vec()
513498
} else {
514-
get_coinbase_intervals_testnet().to_vec()
499+
COINBASE_INTERVALS_TESTNET.to_vec()
515500
}
516501
}
517502

stacks-common/src/types/tests.rs

Lines changed: 33 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -18,166 +18,163 @@ use super::{
1818
set_test_coinbase_schedule, CoinbaseInterval, StacksEpochId, COINBASE_INTERVALS_MAINNET,
1919
COINBASE_INTERVALS_TESTNET,
2020
};
21-
use crate::types::{get_coinbase_intervals_mainnet, get_coinbase_intervals_testnet};
2221

2322
#[test]
2423
fn test_mainnet_coinbase_emissions() {
25-
let coinbase_intervals_mainnet = get_coinbase_intervals_mainnet();
26-
assert_eq!(coinbase_intervals_mainnet.len(), 5);
27-
assert_eq!(coinbase_intervals_mainnet[0].coinbase, 1_000_000_000);
28-
assert_eq!(coinbase_intervals_mainnet[1].coinbase, 500_000_000);
29-
assert_eq!(coinbase_intervals_mainnet[2].coinbase, 250_000_000);
30-
assert_eq!(coinbase_intervals_mainnet[3].coinbase, 125_000_000);
31-
assert_eq!(coinbase_intervals_mainnet[4].coinbase, 62_500_000);
24+
assert_eq!(COINBASE_INTERVALS_MAINNET.len(), 5);
25+
assert_eq!(COINBASE_INTERVALS_MAINNET[0].coinbase, 1_000_000_000);
26+
assert_eq!(COINBASE_INTERVALS_MAINNET[1].coinbase, 500_000_000);
27+
assert_eq!(COINBASE_INTERVALS_MAINNET[2].coinbase, 250_000_000);
28+
assert_eq!(COINBASE_INTERVALS_MAINNET[3].coinbase, 125_000_000);
29+
assert_eq!(COINBASE_INTERVALS_MAINNET[4].coinbase, 62_500_000);
3230

3331
// heights from SIP-029
3432
assert_eq!(
35-
coinbase_intervals_mainnet[0].effective_start_height,
33+
COINBASE_INTERVALS_MAINNET[0].effective_start_height,
3634
666_050 - 666_050
3735
);
3836
assert_eq!(
39-
coinbase_intervals_mainnet[1].effective_start_height,
37+
COINBASE_INTERVALS_MAINNET[1].effective_start_height,
4038
945_000 - 666_050
4139
);
4240
assert_eq!(
43-
coinbase_intervals_mainnet[2].effective_start_height,
41+
COINBASE_INTERVALS_MAINNET[2].effective_start_height,
4442
1_050_000 - 666_050
4543
);
4644
assert_eq!(
47-
coinbase_intervals_mainnet[3].effective_start_height,
45+
COINBASE_INTERVALS_MAINNET[3].effective_start_height,
4846
1_260_000 - 666_050
4947
);
5048
assert_eq!(
51-
coinbase_intervals_mainnet[4].effective_start_height,
49+
COINBASE_INTERVALS_MAINNET[4].effective_start_height,
5250
1_470_000 - 666_050
5351
);
5452
}
5553

5654
#[test]
5755
fn test_get_coinbase_at_effective_height() {
58-
let coinbase_intervals_mainnet = get_coinbase_intervals_mainnet();
59-
assert!(CoinbaseInterval::check_order(coinbase_intervals_mainnet));
56+
assert!(CoinbaseInterval::check_order(&*COINBASE_INTERVALS_MAINNET));
6057

6158
assert_eq!(
6259
CoinbaseInterval::get_coinbase_at_effective_height(
63-
coinbase_intervals_mainnet,
60+
&*COINBASE_INTERVALS_MAINNET,
6461
666050 - 666050
6562
),
6663
1_000_000_000
6764
);
6865
assert_eq!(
6966
CoinbaseInterval::get_coinbase_at_effective_height(
70-
coinbase_intervals_mainnet,
67+
&*COINBASE_INTERVALS_MAINNET,
7168
666051 - 666050
7269
),
7370
1_000_000_000
7471
);
7572

7673
assert_eq!(
7774
CoinbaseInterval::get_coinbase_at_effective_height(
78-
coinbase_intervals_mainnet,
75+
&*COINBASE_INTERVALS_MAINNET,
7976
944_999 - 666050
8077
),
8178
1_000_000_000
8279
);
8380
assert_eq!(
8481
CoinbaseInterval::get_coinbase_at_effective_height(
85-
coinbase_intervals_mainnet,
82+
&*COINBASE_INTERVALS_MAINNET,
8683
945_000 - 666050
8784
),
8885
500_000_000
8986
);
9087
assert_eq!(
9188
CoinbaseInterval::get_coinbase_at_effective_height(
92-
coinbase_intervals_mainnet,
89+
&*COINBASE_INTERVALS_MAINNET,
9390
945_001 - 666050
9491
),
9592
500_000_000
9693
);
9794

9895
assert_eq!(
9996
CoinbaseInterval::get_coinbase_at_effective_height(
100-
coinbase_intervals_mainnet,
97+
&*COINBASE_INTERVALS_MAINNET,
10198
1_049_999 - 666050
10299
),
103100
500_000_000
104101
);
105102
assert_eq!(
106103
CoinbaseInterval::get_coinbase_at_effective_height(
107-
coinbase_intervals_mainnet,
104+
&*COINBASE_INTERVALS_MAINNET,
108105
1_050_000 - 666050
109106
),
110107
250_000_000
111108
);
112109
assert_eq!(
113110
CoinbaseInterval::get_coinbase_at_effective_height(
114-
coinbase_intervals_mainnet,
111+
&*COINBASE_INTERVALS_MAINNET,
115112
1_050_001 - 666050
116113
),
117114
250_000_000
118115
);
119116

120117
assert_eq!(
121118
CoinbaseInterval::get_coinbase_at_effective_height(
122-
coinbase_intervals_mainnet,
119+
&*COINBASE_INTERVALS_MAINNET,
123120
1_259_999 - 666050
124121
),
125122
250_000_000
126123
);
127124
assert_eq!(
128125
CoinbaseInterval::get_coinbase_at_effective_height(
129-
coinbase_intervals_mainnet,
126+
&*COINBASE_INTERVALS_MAINNET,
130127
1_260_000 - 666050
131128
),
132129
125_000_000
133130
);
134131
assert_eq!(
135132
CoinbaseInterval::get_coinbase_at_effective_height(
136-
coinbase_intervals_mainnet,
133+
&*COINBASE_INTERVALS_MAINNET,
137134
1_260_001 - 666050
138135
),
139136
125_000_000
140137
);
141138

142139
assert_eq!(
143140
CoinbaseInterval::get_coinbase_at_effective_height(
144-
coinbase_intervals_mainnet,
141+
&*COINBASE_INTERVALS_MAINNET,
145142
1_469_999 - 666050
146143
),
147144
125_000_000
148145
);
149146
assert_eq!(
150147
CoinbaseInterval::get_coinbase_at_effective_height(
151-
coinbase_intervals_mainnet,
148+
&*COINBASE_INTERVALS_MAINNET,
152149
1_470_000 - 666050
153150
),
154151
62_500_000
155152
);
156153
assert_eq!(
157154
CoinbaseInterval::get_coinbase_at_effective_height(
158-
coinbase_intervals_mainnet,
155+
&*COINBASE_INTERVALS_MAINNET,
159156
1_470_001 - 666050
160157
),
161158
62_500_000
162159
);
163160

164161
assert_eq!(
165162
CoinbaseInterval::get_coinbase_at_effective_height(
166-
coinbase_intervals_mainnet,
163+
&*COINBASE_INTERVALS_MAINNET,
167164
2_197_559 - 666050
168165
),
169166
62_500_000
170167
);
171168
assert_eq!(
172169
CoinbaseInterval::get_coinbase_at_effective_height(
173-
coinbase_intervals_mainnet,
170+
&*COINBASE_INTERVALS_MAINNET,
174171
2_197_560 - 666050
175172
),
176173
62_500_000
177174
);
178175
assert_eq!(
179176
CoinbaseInterval::get_coinbase_at_effective_height(
180-
coinbase_intervals_mainnet,
177+
&*COINBASE_INTERVALS_MAINNET,
181178
2_197_561 - 666050
182179
),
183180
62_500_000
@@ -330,11 +327,11 @@ fn test_set_coinbase_intervals() {
330327

331328
assert_eq!(
332329
StacksEpochId::get_coinbase_intervals(true),
333-
get_coinbase_intervals_mainnet()
330+
*COINBASE_INTERVALS_MAINNET
334331
);
335332
assert_eq!(
336333
StacksEpochId::get_coinbase_intervals(false),
337-
get_coinbase_intervals_testnet()
334+
*COINBASE_INTERVALS_TESTNET
338335
);
339336

340337
set_test_coinbase_schedule(Some(new_sched.clone()));
@@ -346,10 +343,10 @@ fn test_set_coinbase_intervals() {
346343

347344
assert_eq!(
348345
StacksEpochId::get_coinbase_intervals(true),
349-
get_coinbase_intervals_mainnet()
346+
*COINBASE_INTERVALS_MAINNET
350347
);
351348
assert_eq!(
352349
StacksEpochId::get_coinbase_intervals(false),
353-
get_coinbase_intervals_testnet()
350+
*COINBASE_INTERVALS_TESTNET
354351
);
355352
}

0 commit comments

Comments
 (0)