Skip to content

Commit 3a95354

Browse files
committed
chore(data_structures): set WIP0028 (V1_8) launch date at 18 February 2025, 9am UTC
1 parent 9ac779f commit 3a95354

File tree

5 files changed

+60
-110
lines changed

5 files changed

+60
-110
lines changed

config/src/defaults.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,12 @@ pub trait Defaults {
482482
}
483483

484484
fn protocol_versions(&self) -> HashMap<ProtocolVersion, (Epoch, u16)> {
485-
[(ProtocolVersion::V1_7, (0, 45))].into_iter().collect()
485+
[
486+
(ProtocolVersion::V1_7, (0, 45)),
487+
(ProtocolVersion::V1_8, (3_048_961, 45)),
488+
]
489+
.into_iter()
490+
.collect()
486491
}
487492
}
488493

data_structures/src/chain/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ impl ConsensusConstantsWit2 {
305305
80 + 21 // One hour + one superepoch for final confirmation
306306
}
307307
_ => {
308-
13_440 + 21 // 1 week + one superepoch for final confirmation
308+
13_440 // 1 week
309309
}
310310
}
311311
}

data_structures/src/chain/tapi.rs

+26-83
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
1-
use crate::{
2-
chain::{ChainInfo, Environment, Epoch, PublicKeyHash},
3-
register_protocol_version, ProtocolVersion,
4-
};
1+
use crate::chain::{Environment, Epoch, PublicKeyHash};
52
use serde::{Deserialize, Serialize};
63
use std::collections::{HashMap, HashSet};
74

8-
const ONE_HOUR: u32 = 80;
9-
const TWO_WEEKS: u32 = 26_880;
5+
// const ONE_HOUR: u32 = 80;
6+
// const TWO_WEEKS: u32 = 26_880;
107

118
/// Committee for superblock indices 750-1344
129
const FIRST_EMERGENCY_COMMITTEE: [&str; 7] = [
@@ -89,8 +86,7 @@ pub fn wip_info() -> HashMap<String, Epoch> {
8986
active_wips.insert("WIP0025".to_string(), 1708901);
9087
active_wips.insert("WIP0026".to_string(), 1708901);
9188
active_wips.insert("WIP0027".to_string(), 1708901);
92-
// TODO: Add epoch when WIP0028 was activated
93-
// active_wips.insert("WIP0028".to_string(), 2949141);
89+
active_wips.insert("WIP0028".to_string(), 3048961);
9490

9591
active_wips
9692
}
@@ -110,7 +106,7 @@ fn test_wip_info() -> HashMap<String, Epoch> {
110106
active_wips.insert("WIP0025".to_string(), 0);
111107
active_wips.insert("WIP0026".to_string(), 0);
112108
active_wips.insert("WIP0027".to_string(), 0);
113-
// active_wips.insert("WIP0028".to_string(), 0);
109+
active_wips.insert("WIP0028".to_string(), 0);
114110

115111
active_wips
116112
}
@@ -140,8 +136,6 @@ impl TapiEngine {
140136
epoch_to_update: Epoch,
141137
block_epoch: Epoch,
142138
avoid_wip_list: &HashSet<String>,
143-
checkpoints_period: u16,
144-
chain_info: &mut ChainInfo,
145139
) {
146140
// In case of empty epochs, they would be considered as blocks with tapi version to 0
147141
// In order to not update bit counter from old blocks where the block version was not used,
@@ -152,14 +146,7 @@ impl TapiEngine {
152146
let init = self.bit_tapi_counter.last_epoch + 1;
153147
let end = epoch_to_update;
154148
for i in init..end {
155-
self.update_bit_counter(
156-
0,
157-
i,
158-
block_epoch,
159-
avoid_wip_list,
160-
checkpoints_period,
161-
chain_info,
162-
);
149+
self.update_bit_counter(0, i, block_epoch, avoid_wip_list);
163150
}
164151
}
165152
for n in 0..self.bit_tapi_counter.len() {
@@ -184,21 +171,6 @@ impl TapiEngine {
184171
let scheduled_epoch = block_epoch + 21;
185172
self.wip_activation
186173
.insert(bit_counter.wip.clone(), scheduled_epoch);
187-
if bit_counter.wip == "WIP0028" {
188-
log::info!("WIP0028 has passed. Protocol V1_8 will be scheduled for epoch {}", scheduled_epoch);
189-
register_protocol_version(
190-
ProtocolVersion::V1_8,
191-
scheduled_epoch,
192-
checkpoints_period,
193-
);
194-
// Register the 1_8 protocol into chain state (namely, chain info) so that
195-
// the scheduled activation data eventually gets persisted into storage.
196-
chain_info.protocol.register(
197-
scheduled_epoch,
198-
ProtocolVersion::V1_8,
199-
checkpoints_period,
200-
);
201-
}
202174
}
203175
bit_counter.votes = 0;
204176
}
@@ -212,44 +184,21 @@ impl TapiEngine {
212184
&mut self,
213185
environment: Environment,
214186
) -> (Epoch, HashSet<String>) {
215-
let mut voting_wips = vec![None; 32];
187+
let voting_wips = vec![None; 32];
216188

217189
match environment {
218190
Environment::Mainnet => {
219191
// Hardcoded information about WIPs
220192
for (k, v) in wip_info() {
221193
self.wip_activation.insert(k, v);
222194
}
223-
224-
// Hardcoded information about WIPs in vote processing
225-
let wip_0028 = BitVotesCounter {
226-
votes: 0,
227-
period: TWO_WEEKS,
228-
wip: "WIP0028".to_string(),
229-
// Start signaling on December 14 at 9am UTC
230-
init: 2922240,
231-
end: u32::MAX,
232-
bit: 9,
233-
};
234-
voting_wips[9] = Some(wip_0028);
235195
}
236196
Environment::Testnet | Environment::Development => {
237197
// In non-mainnet chains, all the WIPs that are active in mainnet are considered
238198
// active since epoch 0.
239199
for (k, v) in test_wip_info() {
240200
self.wip_activation.insert(k, v);
241201
}
242-
243-
// Hardcoded information about WIPs in vote processing
244-
let wip_0028 = BitVotesCounter {
245-
votes: 0,
246-
period: ONE_HOUR,
247-
wip: "WIP0028".to_string(),
248-
init: 0,
249-
end: u32::MAX,
250-
bit: 9,
251-
};
252-
voting_wips[9] = Some(wip_0028);
253202
}
254203
};
255204

@@ -457,7 +406,7 @@ pub fn in_emergency_period(
457406
)
458407
} else if Environment::Mainnet == environment
459408
&& superblock_index > 224_300
460-
&& superblock_index < 292_224
409+
&& superblock_index < 304_896
461410
{
462411
Some(
463412
FOURTH_EMERGENCY_COMMITTEE
@@ -705,7 +654,6 @@ mod tests {
705654
#[test]
706655
fn test_update_bit_counter() {
707656
let empty_hs = HashSet::default();
708-
let mut chain_info = ChainInfo::default();
709657
let mut t = TapiEngine::default();
710658
let bit = 0;
711659
let wip = BitVotesCounter {
@@ -719,42 +667,42 @@ mod tests {
719667
t.bit_tapi_counter.insert(wip);
720668
assert_eq!(t.bit_tapi_counter.last_epoch, 0);
721669

722-
t.update_bit_counter(1, 9_999, 9_999, &empty_hs, 45, &mut chain_info);
670+
t.update_bit_counter(1, 9_999, 9_999, &empty_hs);
723671
// Updating with epoch < init does not increase the votes counter
724672
assert_eq!(t.bit_tapi_counter.info[bit].clone().unwrap().votes, 0);
725673
assert_eq!(t.bit_tapi_counter.last_epoch, 9_999);
726674

727-
t.update_bit_counter(1, 10_000, 10_000, &empty_hs, 45, &mut chain_info);
675+
t.update_bit_counter(1, 10_000, 10_000, &empty_hs);
728676
// Updating with epoch >= init does increase the votes counter
729677
// But since this is the first epoch, the votes counter is reset to 0 again afterwards
730678
assert_eq!(t.bit_tapi_counter.info[bit].clone().unwrap().votes, 0);
731679

732-
t.update_bit_counter(1, 10_001, 10_001, &empty_hs, 45, &mut chain_info);
680+
t.update_bit_counter(1, 10_001, 10_001, &empty_hs);
733681
// Updating with epoch >= init does increase the votes counter
734682
assert_eq!(t.bit_tapi_counter.info[bit].clone().unwrap().votes, 1);
735683

736-
t.update_bit_counter(1, 10_002, 10_002, &empty_hs, 45, &mut chain_info);
684+
t.update_bit_counter(1, 10_002, 10_002, &empty_hs);
737685
// Updating with epoch >= init does increase the votes counter
738686
assert_eq!(t.bit_tapi_counter.info[bit].clone().unwrap().votes, 2);
739687

740688
// Updating with an epoch that was already updated will count the votes twice, there is no
741689
// protection against this because the update_new_wip_votes function must be able to count
742690
// votes from old blocks
743691
/*
744-
t.update_bit_counter(1, 10_002, &empty_hs, 45, &mut chain_info);
692+
t.update_bit_counter(1, 10_002, &empty_hs);
745693
*/
746694

747-
t.update_bit_counter(0, 10_003, 10_003, &empty_hs, 45, &mut chain_info);
695+
t.update_bit_counter(0, 10_003, 10_003, &empty_hs);
748696
// Updating with epoch >= init but voting against does not increase the votes counter
749697
assert_eq!(t.bit_tapi_counter.info[bit].clone().unwrap().votes, 2);
750698

751-
t.update_bit_counter(0, 10_103, 10_103, &empty_hs, 45, &mut chain_info);
699+
t.update_bit_counter(0, 10_103, 10_103, &empty_hs);
752700
// The vote counting is at epoch 10_100, the votes should be reset to 0
753701
assert_eq!(t.bit_tapi_counter.info[bit].clone().unwrap().votes, 0);
754702

755703
// Add 90 votes to test activation
756704
for epoch in 10_200..10_290 {
757-
t.update_bit_counter(1, epoch, epoch, &empty_hs, 45, &mut chain_info);
705+
t.update_bit_counter(1, epoch, epoch, &empty_hs);
758706
}
759707
// More than 80% of votes means that the WIP should activate at the next counting epoch
760708
assert_eq!(t.bit_tapi_counter.info[bit].clone().unwrap().votes, 89);
@@ -765,7 +713,7 @@ mod tests {
765713
// so that all the blocks after 10_321 are validated using the new validation logic, or
766714
// change the WIP activation date to 10_501?
767715
// Decided to change the WIP activation date to 10_521
768-
t.update_bit_counter(0, 10_500, 10_500, &empty_hs, 45, &mut chain_info);
716+
t.update_bit_counter(0, 10_500, 10_500, &empty_hs);
769717
// The votes counter should reset
770718
assert_eq!(t.bit_tapi_counter.info[bit].clone().unwrap().votes, 0);
771719
// The activation date should be
@@ -775,7 +723,6 @@ mod tests {
775723
#[test]
776724
fn test_update_bit_counter_multi_vote() {
777725
let empty_hs = HashSet::default();
778-
let mut chain_info = ChainInfo::default();
779726
let mut t = TapiEngine::default();
780727
let wip0 = BitVotesCounter {
781728
votes: 0,
@@ -798,35 +745,35 @@ mod tests {
798745
assert_eq!(t.bit_tapi_counter.last_epoch, 0);
799746

800747
// Vote for none
801-
t.update_bit_counter(0, 10_001, 10_001, &empty_hs, 45, &mut chain_info);
748+
t.update_bit_counter(0, 10_001, 10_001, &empty_hs);
802749
assert_eq!(t.bit_tapi_counter.info[0].clone().unwrap().votes, 0);
803750
assert_eq!(t.bit_tapi_counter.info[1].clone().unwrap().votes, 0);
804751
assert_eq!(t.bit_tapi_counter.last_epoch, 10_001);
805752

806753
// Vote for both
807-
t.update_bit_counter(3, 10_002, 10_002, &empty_hs, 45, &mut chain_info);
754+
t.update_bit_counter(3, 10_002, 10_002, &empty_hs);
808755
assert_eq!(t.bit_tapi_counter.info[0].clone().unwrap().votes, 1);
809756
assert_eq!(t.bit_tapi_counter.info[1].clone().unwrap().votes, 1);
810757

811758
// Vote only for wip0
812-
t.update_bit_counter(1, 10_002, 10_002, &empty_hs, 45, &mut chain_info);
759+
t.update_bit_counter(1, 10_002, 10_002, &empty_hs);
813760
assert_eq!(t.bit_tapi_counter.info[0].clone().unwrap().votes, 2);
814761
assert_eq!(t.bit_tapi_counter.info[1].clone().unwrap().votes, 1);
815762

816763
// Vote only for wip1
817-
t.update_bit_counter(2, 10_002, 10_002, &empty_hs, 45, &mut chain_info);
764+
t.update_bit_counter(2, 10_002, 10_002, &empty_hs);
818765
assert_eq!(t.bit_tapi_counter.info[0].clone().unwrap().votes, 2);
819766
assert_eq!(t.bit_tapi_counter.info[1].clone().unwrap().votes, 2);
820767

821768
// Add 90 votes to test activation of both wips in the same epoch
822769
for epoch in 10_003..10_093 {
823-
t.update_bit_counter(3, epoch, epoch, &empty_hs, 45, &mut chain_info);
770+
t.update_bit_counter(3, epoch, epoch, &empty_hs);
824771
}
825772

826773
assert_eq!(t.bit_tapi_counter.info[0].clone().unwrap().votes, 92);
827774
assert_eq!(t.bit_tapi_counter.info[1].clone().unwrap().votes, 92);
828775

829-
t.update_bit_counter(0, 10_100, 10_100, &empty_hs, 45, &mut chain_info);
776+
t.update_bit_counter(0, 10_100, 10_100, &empty_hs);
830777
// The votes counter should reset
831778
assert_eq!(t.bit_tapi_counter.info[0].clone().unwrap().votes, 0);
832779
assert_eq!(t.bit_tapi_counter.info[1].clone().unwrap().votes, 0);
@@ -840,7 +787,6 @@ mod tests {
840787
// Check that voting for unallocated wips is allowed, but the extra votes are not counted,
841788
// and the votes for active bits are valid
842789
let empty_hs = HashSet::default();
843-
let mut chain_info = ChainInfo::default();
844790
let mut t = TapiEngine::default();
845791
let bit = 0;
846792
let wip = BitVotesCounter {
@@ -855,7 +801,7 @@ mod tests {
855801
assert_eq!(t.bit_tapi_counter.info[bit].clone().unwrap().votes, 0);
856802

857803
// Vote "yes" to all the 32 bits, even though there is only 1 active wip (bit 0)
858-
t.update_bit_counter(u32::MAX, 10_001, 10_001, &empty_hs, 45, &mut chain_info);
804+
t.update_bit_counter(u32::MAX, 10_001, 10_001, &empty_hs);
859805
// This is a valid block and a valid vote
860806
assert_eq!(t.bit_tapi_counter.info[bit].clone().unwrap().votes, 1);
861807
}
@@ -866,8 +812,7 @@ mod tests {
866812

867813
let (epoch, old_wips) = t.initialize_wip_information(Environment::Mainnet);
868814
// The first block whose vote must be counted is the one from WIP0028
869-
let init_epoch_wip0028 = 2922240;
870-
assert_eq!(epoch, init_epoch_wip0028);
815+
assert_eq!(epoch, u32::MAX);
871816
// The TapiEngine was just created, there list of old_wips must be empty
872817
assert_eq!(old_wips, HashSet::new());
873818
// The list of active WIPs should match those defined in `wip_info`
@@ -879,9 +824,7 @@ mod tests {
879824

880825
// Test initialize_wip_information with a non-empty TapiEngine
881826
let (epoch, old_wips) = t.initialize_wip_information(Environment::Mainnet);
882-
// WIP0022 is already included and it won't be updated
883-
let mut hs = HashSet::new();
884-
hs.insert("WIP0028".to_string());
827+
let hs = HashSet::new();
885828
assert_eq!(old_wips, hs);
886829

887830
// There is no new WIPs to update so we obtain the max value

data_structures/src/superblock.rs

+19-7
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,13 @@ use crate::{
2121
Environment,
2222
};
2323

24-
/// TODO: Committee for superblock indices during the bootstrapping of wit/2
25-
const WIT2_BOOTSTRAP_COMMITTEE: [&str; 0] = [];
24+
/// TODO: Add nodes to the committee for superblock voting during the bootstrapping of wit/2
25+
const WIT2_BOOTSTRAP_COMMITTEE: [&str; 4] = [
26+
"wit1pfj66p7n2x7dgrwh4cf0ylhd959e8v9evfh09z",
27+
"wit18ac3gly2xln0mtpp2k5rvs05rph2skef6ywnwd",
28+
"wit1gdn3d07njg0klyvldl8tq07h8ltm93uytgjj6x",
29+
"wit1llz4vw9mszjqud5pqavf84208entwz73lxekzm",
30+
];
2631

2732
/// Committee for superblock indices during the bootstrapping of wit/2
2833
const WIT2_BOOTSTRAP_COMMITTEE_TEST: [&str; 4] = [
@@ -471,11 +476,18 @@ impl SuperBlockState {
471476
// Override superblock signing committee during the bootstrapping of wit/2
472477
self.signing_committee = match get_environment() {
473478
Environment::Mainnet => {
474-
// wit/2 activates at 2_922_240 + 14 x 1_920 (TAPI delay) + 7 x 1_920 (instant activation delay) = 2_962_560
475-
// disabling the activation committee at 299_712 implies we add an extra 8 weeks worth of time (8 x 4320)
476-
// to inplement a decentralized superblock committee selection mechanism. Note that any delay in activating
477-
// wit/2 will essentially be subtracted from the extra 8 weeks,
478-
if (292_224..299_712).contains(&superblock_index) {
479+
// wit/2 activation timeline and superblock bootstrap committee:
480+
// Release is scheduled at 11th of February, V1_8 activation enters into force at epoch 3_048_961
481+
// A stake threshold of 300M needs to be reached before V2_0 will be scheduled (assume this takes a week)
482+
// Add 7 x 1_920 epochs to take into account the activation delay for V2_0
483+
// 3_048_961 + 7 x 1_920 + 7 x 1_920 = 3_075_841
484+
//
485+
// wit/2.0 should now activated with a fixed superblock bootstrap committee
486+
//
487+
// Add 8 x 7 x 4320 epochs to implement a decentralized superblock committee selection mechanism
488+
// Any delay in activating wit/2.0 will essentially be subtracted from these 8 weeks
489+
// 3_075_841 + 8 x 7 x 4320 = 3_317_761
490+
if (304_896..331_776).contains(&superblock_index) {
479491
WIT2_BOOTSTRAP_COMMITTEE
480492
.iter()
481493
.map(|address| address.parse().expect("Malformed signing committee"))

0 commit comments

Comments
 (0)