Skip to content

Commit 33a49c4

Browse files
committed
feat(data_structures): partially implement versioning for PoIs
1 parent dc3d1b0 commit 33a49c4

File tree

13 files changed

+272
-144
lines changed

13 files changed

+272
-144
lines changed

data_structures/src/chain/mod.rs

+40-20
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ use crate::{
4040
},
4141
get_environment,
4242
proto::{
43-
versioning::{ProtocolVersion, Versioned},
43+
versioning::{ProtocolVersion, Versioned, VersionedHashable},
4444
ProtobufConvert,
4545
},
4646
staking::prelude::*,
@@ -756,13 +756,13 @@ pub struct BlockMerkleRoots {
756756
}
757757

758758
/// Function to calculate a merkle tree from a transaction vector
759-
pub fn merkle_tree_root<T>(transactions: &[T]) -> Hash
759+
pub fn merkle_tree_root<T>(transactions: &[T], protocol_version: ProtocolVersion) -> Hash
760760
where
761-
T: Hashable,
761+
T: VersionedHashable,
762762
{
763763
let transactions_hashes: Vec<Sha256> = transactions
764764
.iter()
765-
.map(|x| match x.hash() {
765+
.map(|x| match x.versioned_hash(protocol_version) {
766766
Hash::SHA256(x) => Sha256(x),
767767
})
768768
.collect();
@@ -773,16 +773,16 @@ where
773773
}
774774

775775
impl BlockMerkleRoots {
776-
pub fn from_transactions(txns: &BlockTransactions) -> Self {
776+
pub fn from_transactions(txns: &BlockTransactions, protocol_version: ProtocolVersion) -> Self {
777777
BlockMerkleRoots {
778-
mint_hash: txns.mint.hash(),
779-
vt_hash_merkle_root: merkle_tree_root(&txns.value_transfer_txns),
780-
dr_hash_merkle_root: merkle_tree_root(&txns.data_request_txns),
781-
commit_hash_merkle_root: merkle_tree_root(&txns.commit_txns),
782-
reveal_hash_merkle_root: merkle_tree_root(&txns.reveal_txns),
783-
tally_hash_merkle_root: merkle_tree_root(&txns.tally_txns),
784-
stake_hash_merkle_root: merkle_tree_root(&txns.stake_txns),
785-
unstake_hash_merkle_root: merkle_tree_root(&txns.unstake_txns),
778+
mint_hash: txns.mint.versioned_hash(protocol_version),
779+
vt_hash_merkle_root: merkle_tree_root(&txns.value_transfer_txns, protocol_version),
780+
dr_hash_merkle_root: merkle_tree_root(&txns.data_request_txns, protocol_version),
781+
commit_hash_merkle_root: merkle_tree_root(&txns.commit_txns, protocol_version),
782+
reveal_hash_merkle_root: merkle_tree_root(&txns.reveal_txns, protocol_version),
783+
tally_hash_merkle_root: merkle_tree_root(&txns.tally_txns, protocol_version),
784+
stake_hash_merkle_root: merkle_tree_root(&txns.stake_txns, protocol_version),
785+
unstake_hash_merkle_root: merkle_tree_root(&txns.unstake_txns, protocol_version),
786786
}
787787
}
788788
}
@@ -901,13 +901,13 @@ impl SuperBlock {
901901
&self,
902902
blocks: &[Block],
903903
tally_tx: &TallyTransaction,
904+
protocol_version: ProtocolVersion,
904905
) -> Option<TxInclusionProof> {
905906
// Get the PoI for the block root, if the tally transaction is found on the list of blocks
906907
// Obtain also the index of the tally root of the block containing the tally TX.
907-
let (mut poi, tally_root_idx) = blocks
908-
.iter()
909-
.enumerate()
910-
.find_map(|(idx, b)| Some((tally_tx.data_proof_of_inclusion(b)?, idx)))?;
908+
let (mut poi, tally_root_idx) = blocks.iter().enumerate().find_map(|(idx, b)| {
909+
Some((tally_tx.data_proof_of_inclusion(b, protocol_version)?, idx))
910+
})?;
911911

912912
// Collect all tally roots from the blocks
913913
let tally_roots = blocks
@@ -4726,10 +4726,11 @@ mod tests {
47264726
expected_lemma_lengths: Vec<usize>,
47274727
blocks: Vec<Block>,
47284728
tally_txs: Vec<TallyTransaction>,
4729+
protocol_version: ProtocolVersion,
47294730
) {
47304731
for index in 0..expected_indices.len() {
47314732
let result = sb
4732-
.tally_proof_of_inclusion(&blocks, &tally_txs[index])
4733+
.tally_proof_of_inclusion(&blocks, &tally_txs[index], protocol_version)
47334734
.unwrap();
47344735
assert_eq!(result.index, expected_indices[index]);
47354736
assert_eq!(result.lemma.len(), expected_lemma_lengths[index]);
@@ -6883,6 +6884,7 @@ mod tests {
68836884
1,
68846885
Hash::default(),
68856886
1,
6887+
ProtocolVersion::default(),
68866888
);
68876889

68886890
let expected_indices = vec![0, 2, 2];
@@ -6937,6 +6939,7 @@ mod tests {
69376939
1,
69386940
Hash::default(),
69396941
1,
6942+
ProtocolVersion::default(),
69406943
);
69416944

69426945
let expected_indices = vec![0, 2, 2, 8, 10, 6, 4, 6];
@@ -6972,6 +6975,7 @@ mod tests {
69726975
1,
69736976
Hash::default(),
69746977
1,
6978+
ProtocolVersion::default(),
69756979
);
69766980

69776981
let result = sb.dr_proof_of_inclusion(&[b1, b2], &dr_txs[2]);
@@ -6982,7 +6986,14 @@ mod tests {
69826986
fn test_dr_merkle_root_no_block() {
69836987
let dr_txs = build_test_dr_txs(3);
69846988

6985-
let sb = mining_build_superblock(&[], &[Hash::default()], 1, Hash::default(), 1);
6989+
let sb = mining_build_superblock(
6990+
&[],
6991+
&[Hash::default()],
6992+
1,
6993+
Hash::default(),
6994+
1,
6995+
ProtocolVersion::default(),
6996+
);
69866997

69876998
let result = sb.dr_proof_of_inclusion(&[], &dr_txs[2]);
69886999
assert!(result.is_none());
@@ -7008,6 +7019,7 @@ mod tests {
70087019
1,
70097020
Hash::default(),
70107021
1,
7022+
ProtocolVersion::default(),
70117023
);
70127024

70137025
let expected_indices = vec![0, 2];
@@ -7046,6 +7058,7 @@ mod tests {
70467058
1,
70477059
Hash::default(),
70487060
1,
7061+
ProtocolVersion::default(),
70497062
);
70507063

70517064
let expected_indices = vec![0, 2, 2];
@@ -7057,6 +7070,7 @@ mod tests {
70577070
expected_lemma_lengths,
70587071
vec![b1, b2],
70597072
tally_txs,
7073+
ProtocolVersion::default(),
70607074
);
70617075
}
70627076

@@ -7108,6 +7122,7 @@ mod tests {
71087122
1,
71097123
Hash::default(),
71107124
1,
7125+
ProtocolVersion::default(),
71117126
);
71127127

71137128
let expected_indices = vec![0, 2, 2, 8, 10, 6, 4, 6];
@@ -7119,12 +7134,14 @@ mod tests {
71197134
expected_lemma_lengths,
71207135
vec![b1, b2, b3],
71217136
tally_txs,
7137+
ProtocolVersion::default(),
71227138
);
71237139
}
71247140

71257141
#[test]
71267142
fn test_tally_merkle_root_none() {
71277143
let tally_txs = build_test_tally_txs(3);
7144+
let protocol_version = ProtocolVersion::default();
71287145

71297146
let mut b1 = block_example();
71307147
let mut b2 = block_example();
@@ -7143,9 +7160,10 @@ mod tests {
71437160
1,
71447161
Hash::default(),
71457162
1,
7163+
ProtocolVersion::default(),
71467164
);
71477165

7148-
let result = sb.tally_proof_of_inclusion(&[b1, b2], &tally_txs[2]);
7166+
let result = sb.tally_proof_of_inclusion(&[b1, b2], &tally_txs[2], protocol_version);
71497167
assert!(result.is_none());
71507168
}
71517169

@@ -7174,6 +7192,7 @@ mod tests {
71747192
1,
71757193
Hash::default(),
71767194
1,
7195+
ProtocolVersion::default(),
71777196
);
71787197

71797198
let expected_indices = vec![0, 2, 2];
@@ -7185,6 +7204,7 @@ mod tests {
71857204
expected_lemma_lengths,
71867205
vec![b1],
71877206
tally_txs,
7207+
ProtocolVersion::default(),
71887208
);
71897209
}
71907210

data_structures/src/lib.rs

+9-10
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,9 @@ use std::sync::RwLock;
1717

1818
use lazy_static::lazy_static;
1919

20-
use crate::proto::versioning::ProtocolInfo;
2120
use crate::{
2221
chain::{Environment, Epoch},
23-
proto::versioning::ProtocolVersion,
22+
proto::versioning::{ProtocolInfo, ProtocolVersion},
2423
};
2524

2625
pub const DEFAULT_VALIDATOR_COUNT_FOR_TESTS: usize = 1000;
@@ -163,7 +162,7 @@ pub fn set_protocol_version(protocol_version: ProtocolVersion) {
163162
/// Refresh the protocol version, i.e. derive the current version from the current epoch, and update `current_version`
164163
/// accordingly.
165164
pub fn refresh_protocol_version(current_epoch: Epoch) {
166-
let current_version = get_protocol_version(Some(current_epoch));
165+
let current_version = ProtocolVersion::from_epoch(current_epoch);
167166
set_protocol_version(current_version)
168167
}
169168

@@ -200,7 +199,7 @@ mod tests {
200199
// If this default changes before the transition to V2 is complete, almost everything will
201200
// break because data structures change schema and, serialization changes and hash
202201
// derivation breaks too
203-
let protocol_version = get_protocol_version(None);
202+
let protocol_version = ProtocolVersion::guess();
204203
assert_eq!(protocol_version, ProtocolVersion::V1_7);
205204

206205
// Register the different protocol versions
@@ -209,23 +208,23 @@ mod tests {
209208
register_protocol_version(ProtocolVersion::V2_0, 300, 20);
210209

211210
// The initial protocol version should be the default one
212-
let version = get_protocol_version(Some(0));
211+
let version = ProtocolVersion::from_epoch(0);
213212
assert_eq!(version, ProtocolVersion::V1_7);
214213

215214
// Right after the
216-
let version = get_protocol_version(Some(100));
215+
let version = ProtocolVersion::from_epoch(100);
217216
assert_eq!(version, ProtocolVersion::V1_7);
218-
let version = get_protocol_version(Some(200));
217+
let version = ProtocolVersion::from_epoch(200);
219218
assert_eq!(version, ProtocolVersion::V1_8);
220-
let version = get_protocol_version(Some(300));
219+
let version = ProtocolVersion::from_epoch(300);
221220
assert_eq!(version, ProtocolVersion::V2_0);
222221

223-
let version = get_protocol_version(None);
222+
let version = ProtocolVersion::guess();
224223
assert_eq!(version, ProtocolVersion::V1_7);
225224

226225
set_protocol_version(ProtocolVersion::V2_0);
227226

228-
let version = get_protocol_version(None);
227+
let version = ProtocolVersion::guess();
229228
assert_eq!(version, ProtocolVersion::V2_0);
230229
}
231230
}

data_structures/src/proto/versioning.rs

+4
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ impl ProtocolVersion {
9191
pub fn guess() -> Self {
9292
get_protocol_version(None)
9393
}
94+
95+
pub fn from_epoch(epoch: Epoch) -> Self {
96+
get_protocol_version(Some(epoch))
97+
}
9498
}
9599

96100
impl PartialOrd for ProtocolVersion {

data_structures/src/superblock.rs

+32-6
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,7 @@ impl SuperBlockState {
424424
sync_superblock: Option<SuperBlock>,
425425
block_epoch: Epoch,
426426
) -> SuperBlock {
427+
let protocol_version = ProtocolVersion::from_epoch(block_epoch);
427428
let key_leaves = hash_key_leaves(&ars_identities.get_rep_ordered_bn256_list(alt_keys));
428429

429430
self.update_ars_identities(ars_identities);
@@ -474,6 +475,7 @@ impl SuperBlockState {
474475
superblock_index,
475476
last_block_in_previous_superblock,
476477
self.signing_committee.len() as u32,
478+
protocol_version,
477479
)
478480
};
479481

@@ -679,6 +681,7 @@ pub fn mining_build_superblock(
679681
index: u32,
680682
last_block_in_previous_superblock: Hash,
681683
signing_committee_length: u32,
684+
protocol_version: ProtocolVersion,
682685
) -> SuperBlock {
683686
let last_block = block_headers.last();
684687
match last_block {
@@ -704,7 +707,7 @@ pub fn mining_build_superblock(
704707
)
705708
}
706709
Some(last_block_header) => {
707-
let last_block_hash = last_block_header.versioned_hash(ProtocolVersion::guess());
710+
let last_block_hash = last_block_header.versioned_hash(protocol_version);
708711
let merkle_drs: Vec<Hash> = block_headers
709712
.iter()
710713
.map(|b| b.merkle_roots.dr_hash_merkle_root)
@@ -717,7 +720,13 @@ pub fn mining_build_superblock(
717720
let ars_root = hash_merkle_tree_root(ars_ordered_hash_leaves);
718721
let blocks: Vec<_> = block_headers
719722
.iter()
720-
.map(|b| format!("#{}: {}", b.beacon.checkpoint, b.hash()))
723+
.map(|b| {
724+
format!(
725+
"#{}: {}",
726+
b.beacon.checkpoint,
727+
b.versioned_hash(protocol_version)
728+
)
729+
})
721730
.collect();
722731
log::trace!(
723732
"Created superblock #{} with hash_prev_block {}, ARS {}, signing_committee_length: {}, blocks {:?}",
@@ -775,7 +784,8 @@ mod tests {
775784
#[test]
776785
fn test_superblock_creation_no_blocks() {
777786
let default_hash = Hash::default();
778-
let superblock = mining_build_superblock(&[], &[], 0, default_hash, 0);
787+
let superblock =
788+
mining_build_superblock(&[], &[], 0, default_hash, 0, ProtocolVersion::default());
779789

780790
let expected = SuperBlock::new(
781791
0,
@@ -833,7 +843,14 @@ mod tests {
833843
tally_merkle_root_1,
834844
);
835845

836-
let superblock = mining_build_superblock(&[block], &[default_hash], 0, default_hash, 1);
846+
let superblock = mining_build_superblock(
847+
&[block],
848+
&[default_hash],
849+
0,
850+
default_hash,
851+
1,
852+
ProtocolVersion::default(),
853+
);
837854
assert_eq!(superblock, expected_superblock);
838855
}
839856

@@ -901,8 +918,14 @@ mod tests {
901918
expected_superblock_tally_root,
902919
);
903920

904-
let superblock =
905-
mining_build_superblock(&[block_1, block_2], &[default_hash], 0, default_hash, 1);
921+
let superblock = mining_build_superblock(
922+
&[block_1, block_2],
923+
&[default_hash],
924+
0,
925+
default_hash,
926+
1,
927+
ProtocolVersion::default(),
928+
);
906929
assert_eq!(superblock, expected_superblock);
907930
}
908931

@@ -1917,6 +1940,7 @@ mod tests {
19171940
1,
19181941
genesis_hash,
19191942
3,
1943+
ProtocolVersion::default(),
19201944
);
19211945
let sb2_hash = expected_sb2.hash();
19221946

@@ -2018,6 +2042,7 @@ mod tests {
20182042
1,
20192043
genesis_hash,
20202044
2,
2045+
ProtocolVersion::default(),
20212046
);
20222047

20232048
assert_eq!(sb2, expected_sb2);
@@ -2178,6 +2203,7 @@ mod tests {
21782203
1,
21792204
genesis_hash,
21802205
2,
2206+
ProtocolVersion::default(),
21812207
);
21822208

21832209
assert_eq!(sb2, expected_sb2);

0 commit comments

Comments
 (0)