Skip to content

Commit f6c1c54

Browse files
authored
Merge pull request #1287 from subspace/better-pieces-abstractions
Better unified piece abstractions using a tiny bit of `unsafe`
2 parents 9247e0a + ca3691d commit f6c1c54

File tree

24 files changed

+453
-434
lines changed

24 files changed

+453
-434
lines changed

crates/pallet-subspace/src/mock.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ use subspace_archiving::archiver::{ArchivedSegment, Archiver};
4141
use subspace_core_primitives::crypto::kzg::{embedded_kzg_settings, Kzg, Witness};
4242
use subspace_core_primitives::crypto::{blake2b_256_254_hash_to_scalar, kzg, ScalarLegacy};
4343
use subspace_core_primitives::{
44-
ArchivedBlockProgress, Blake2b256Hash, LastArchivedBlock, Piece, Randomness, RecordsRoot,
44+
ArchivedBlockProgress, Blake2b256Hash, LastArchivedBlock, PieceArray, Randomness, RecordsRoot,
4545
RootBlock, SegmentIndex, Solution, SolutionRange, PIECE_SIZE, RECORDED_HISTORY_SEGMENT_SIZE,
4646
};
4747
use subspace_solving::{create_chunk_signature, derive_global_challenge, REWARD_SIGNING_CONTEXT};
@@ -362,7 +362,7 @@ pub fn create_signed_vote(
362362
parent_hash: <Block as BlockT>::Hash,
363363
slot: Slot,
364364
global_randomnesses: &Randomness,
365-
piece: Piece,
365+
piece: &PieceArray,
366366
reward_address: <Test as frame_system::Config>::AccountId,
367367
) -> SignedVote<u64, <Block as BlockT>::Hash, <Test as frame_system::Config>::AccountId> {
368368
let reward_signing_context = schnorrkel::signing_context(REWARD_SIGNING_CONTEXT);
@@ -382,8 +382,8 @@ pub fn create_signed_vote(
382382
sector_index: 0,
383383
total_pieces: NonZeroU64::new(1).unwrap(),
384384
piece_offset: 0,
385-
piece_record_hash: blake2b_256_254_hash_to_scalar(&piece.record()),
386-
piece_witness: Witness::try_from_bytes(&piece.witness()).unwrap(),
385+
piece_record_hash: blake2b_256_254_hash_to_scalar(piece.record().as_ref()),
386+
piece_witness: Witness::try_from_bytes(piece.witness()).unwrap(),
387387
chunk_offset: 0,
388388
chunk,
389389
chunk_signature: create_chunk_signature(keypair, &chunk.to_bytes()),

crates/pallet-subspace/src/tests.rs

+22-23
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ use sp_runtime::transaction_validity::{
4444
use sp_runtime::DispatchError;
4545
use std::assert_matches::assert_matches;
4646
use std::collections::BTreeMap;
47-
use subspace_core_primitives::Piece;
4847
use subspace_runtime_primitives::{FindBlockRewardAddress, FindVotingRewardAddresses};
4948
use subspace_solving::REWARD_SIGNING_CONTEXT;
5049
use subspace_verification::Error as VerificationError;
@@ -628,7 +627,7 @@ fn vote_block_listed() {
628627
new_test_ext().execute_with(|| {
629628
let keypair = Keypair::generate();
630629
let archived_segment = create_archived_segment();
631-
let piece = Piece::from(archived_segment.pieces.as_pieces().next().unwrap());
630+
let piece = &archived_segment.pieces[0];
632631

633632
BlockList::<Test>::insert(
634633
FarmerPublicKey::unchecked_from(keypair.public.to_bytes()),
@@ -658,7 +657,7 @@ fn vote_after_genesis() {
658657
new_test_ext().execute_with(|| {
659658
let keypair = Keypair::generate();
660659
let archived_segment = create_archived_segment();
661-
let piece = Piece::from(archived_segment.pieces.as_pieces().next().unwrap());
660+
let piece = &archived_segment.pieces[0];
662661

663662
// Can't submit vote right after genesis block
664663
let signed_vote = create_signed_vote(
@@ -683,7 +682,7 @@ fn vote_too_low_height() {
683682
new_test_ext().execute_with(|| {
684683
let keypair = Keypair::generate();
685684
let archived_segment = create_archived_segment();
686-
let piece = Piece::from(archived_segment.pieces.as_pieces().next().unwrap());
685+
let piece = &archived_segment.pieces[0];
687686

688687
progress_to_block(&keypair, 1, 1);
689688

@@ -696,7 +695,7 @@ fn vote_too_low_height() {
696695
<Test as frame_system::Config>::Hash::default(),
697696
Subspace::current_slot() + 1,
698697
&Subspace::global_randomnesses().current,
699-
piece.clone(),
698+
piece,
700699
1,
701700
);
702701

@@ -713,7 +712,7 @@ fn vote_past_future_height() {
713712
new_test_ext().execute_with(|| {
714713
let keypair = Keypair::generate();
715714
let archived_segment = create_archived_segment();
716-
let piece = Piece::from(archived_segment.pieces.as_pieces().next().unwrap());
715+
let piece = &archived_segment.pieces[0];
717716

718717
progress_to_block(&keypair, 4, 1);
719718

@@ -725,7 +724,7 @@ fn vote_past_future_height() {
725724
<Test as frame_system::Config>::Hash::default(),
726725
Subspace::current_slot() + 1,
727726
&Subspace::global_randomnesses().current,
728-
piece.clone(),
727+
piece,
729728
1,
730729
);
731730

@@ -760,7 +759,7 @@ fn vote_wrong_parent() {
760759
new_test_ext().execute_with(|| {
761760
let keypair = Keypair::generate();
762761
let archived_segment = create_archived_segment();
763-
let piece = Piece::from(archived_segment.pieces.as_pieces().next().unwrap());
762+
let piece = &archived_segment.pieces[0];
764763

765764
progress_to_block(&keypair, 2, 1);
766765

@@ -787,7 +786,7 @@ fn vote_past_future_slot() {
787786
new_test_ext().execute_with(|| {
788787
let keypair = Keypair::generate();
789788
let archived_segment = create_archived_segment();
790-
let piece = Piece::from(archived_segment.pieces.as_pieces().next().unwrap());
789+
let piece = &archived_segment.pieces[0];
791790

792791
RecordsRoot::<Test>::insert(
793792
archived_segment.root_block.segment_index(),
@@ -809,7 +808,7 @@ fn vote_past_future_slot() {
809808
frame_system::Pallet::<Test>::block_hash(2),
810809
2.into(),
811810
&Subspace::global_randomnesses().current,
812-
piece.clone(),
811+
piece,
813812
1,
814813
);
815814

@@ -845,7 +844,7 @@ fn vote_past_future_slot() {
845844
// in that context it is valid
846845
{
847846
let keypair = Keypair::generate();
848-
let piece = Piece::from(archived_segment.pieces.as_pieces().next().unwrap());
847+
let piece = &archived_segment.pieces[0];
849848

850849
let signed_vote = create_signed_vote(
851850
&keypair,
@@ -885,7 +884,7 @@ fn vote_same_slot() {
885884
// Same time slot in the vote as in the block is fine if height is the same (pre-dispatch)
886885
{
887886
let keypair = Keypair::generate();
888-
let piece = Piece::from(archived_segment.pieces.as_pieces().next().unwrap());
887+
let piece = &archived_segment.pieces[0];
889888
let signed_vote = create_signed_vote(
890889
&keypair,
891890
3,
@@ -903,7 +902,7 @@ fn vote_same_slot() {
903902
// (pre-dispatch)
904903
{
905904
let keypair = Keypair::generate();
906-
let piece = Piece::from(archived_segment.pieces.as_pieces().next().unwrap());
905+
let piece = &archived_segment.pieces[0];
907906
let signed_vote = create_signed_vote(
908907
&keypair,
909908
2,
@@ -927,7 +926,7 @@ fn vote_bad_reward_signature() {
927926
new_test_ext().execute_with(|| {
928927
let keypair = Keypair::generate();
929928
let archived_segment = create_archived_segment();
930-
let piece = Piece::from(archived_segment.pieces.as_pieces().next().unwrap());
929+
let piece = &archived_segment.pieces[0];
931930

932931
progress_to_block(&keypair, 2, 1);
933932

@@ -956,7 +955,7 @@ fn vote_unknown_records_root() {
956955
new_test_ext().execute_with(|| {
957956
let keypair = Keypair::generate();
958957
let archived_segment = create_archived_segment();
959-
let piece = Piece::from(archived_segment.pieces.as_pieces().next().unwrap());
958+
let piece = &archived_segment.pieces[0];
960959

961960
progress_to_block(&keypair, 2, 1);
962961

@@ -983,7 +982,7 @@ fn vote_outside_of_solution_range() {
983982
new_test_ext().execute_with(|| {
984983
let keypair = Keypair::generate();
985984
let archived_segment = create_archived_segment();
986-
let piece = Piece::from(archived_segment.pieces.as_pieces().next().unwrap());
985+
let piece = &archived_segment.pieces[0];
987986

988987
progress_to_block(&keypair, 2, 1);
989988

@@ -1017,7 +1016,7 @@ fn vote_invalid_solution_signature() {
10171016
new_test_ext().execute_with(|| {
10181017
let keypair = Keypair::generate();
10191018
let archived_segment = create_archived_segment();
1020-
let piece = Piece::from(archived_segment.pieces.as_pieces().next().unwrap());
1019+
let piece = &archived_segment.pieces[0];
10211020

10221021
progress_to_block(&keypair, 2, 1);
10231022

@@ -1070,7 +1069,7 @@ fn vote_correct_signature() {
10701069
new_test_ext().execute_with(|| {
10711070
let keypair = Keypair::generate();
10721071
let archived_segment = create_archived_segment();
1073-
let piece = Piece::from(archived_segment.pieces.as_pieces().next().unwrap());
1072+
let piece = &archived_segment.pieces[0];
10741073

10751074
progress_to_block(&keypair, 2, 1);
10761075

@@ -1104,7 +1103,7 @@ fn vote_randomness_update() {
11041103
new_test_ext().execute_with(|| {
11051104
let keypair = Keypair::generate();
11061105
let archived_segment = create_archived_segment();
1107-
let piece = Piece::from(archived_segment.pieces.as_pieces().next().unwrap());
1106+
let piece = &archived_segment.pieces[0];
11081107

11091108
RecordsRoot::<Test>::insert(
11101109
archived_segment.root_block.segment_index(),
@@ -1141,7 +1140,7 @@ fn vote_equivocation_current_block_plus_vote() {
11411140
new_test_ext().execute_with(|| {
11421141
let keypair = Keypair::generate();
11431142
let archived_segment = create_archived_segment();
1144-
let piece = Piece::from(archived_segment.pieces.as_pieces().next().unwrap());
1143+
let piece = &archived_segment.pieces[0];
11451144

11461145
progress_to_block(&keypair, 2, 1);
11471146

@@ -1192,7 +1191,7 @@ fn vote_equivocation_parent_block_plus_vote() {
11921191
new_test_ext().execute_with(|| {
11931192
let keypair = Keypair::generate();
11941193
let archived_segment = create_archived_segment();
1195-
let piece = Piece::from(archived_segment.pieces.as_pieces().next().unwrap());
1194+
let piece = &archived_segment.pieces[0];
11961195

11971196
progress_to_block(&keypair, 2, 1);
11981197

@@ -1252,7 +1251,7 @@ fn vote_equivocation_parent_block_plus_vote() {
12521251
fn vote_equivocation_current_voters_duplicate() {
12531252
new_test_ext().execute_with(|| {
12541253
let archived_segment = create_archived_segment();
1255-
let piece = Piece::from(archived_segment.pieces.as_pieces().next().unwrap());
1254+
let piece = &archived_segment.pieces[0];
12561255

12571256
progress_to_block(&Keypair::generate(), 2, 1);
12581257

@@ -1332,7 +1331,7 @@ fn vote_equivocation_parent_voters_duplicate() {
13321331
new_test_ext().execute_with(|| {
13331332
let keypair = Keypair::generate();
13341333
let archived_segment = create_archived_segment();
1335-
let piece = Piece::from(archived_segment.pieces.as_pieces().next().unwrap());
1334+
let piece = &archived_segment.pieces[0];
13361335

13371336
progress_to_block(&keypair, 2, 1);
13381337

crates/sc-consensus-subspace/src/tests.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,7 @@ async fn run_one_test(mutator: impl Fn(&mut TestHeader, Stage) + Send + Sync + '
549549
.await
550550
.unwrap()
551551
.iter()
552-
.flat_map(|flat_pieces| flat_pieces.as_pieces())
552+
.flat_map(|flat_pieces| flat_pieces.iter())
553553
.enumerate()
554554
.choose(&mut thread_rng())
555555
.map(|(piece_index, piece)| (piece_index as u64, Piece::from(piece)))

crates/sp-lightclient/src/tests.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ impl Farmer {
9191
let kzg = Kzg::new(kzg::embedded_kzg_settings());
9292
let archived_segment = archived_segment(kzg.clone());
9393
let root_block = archived_segment.root_block;
94-
let total_pieces = NonZeroU64::new(archived_segment.pieces.count() as u64).unwrap();
94+
let total_pieces = NonZeroU64::new(archived_segment.pieces.len() as u64).unwrap();
9595
let mut sector = vec![0u8; PLOT_SECTOR_SIZE as usize];
9696
let mut sector_metadata = vec![0u8; SectorMetadata::encoded_size()];
9797
let sector_index = 0;
@@ -150,7 +150,7 @@ impl PieceGetter for TestPieceGetter {
150150
Ok(self
151151
.archived_segment
152152
.pieces
153-
.as_pieces()
153+
.iter()
154154
.nth(piece_index as usize)
155155
.map(Piece::from))
156156
}

crates/subspace-archiving/src/archiver.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use subspace_core_primitives::objects::{
3535
BlockObject, BlockObjectMapping, PieceObject, PieceObjectMapping,
3636
};
3737
use subspace_core_primitives::{
38-
ArchivedBlockProgress, Blake2b256Hash, BlockNumber, FlatPieces, LastArchivedBlock, PieceRef,
38+
ArchivedBlockProgress, Blake2b256Hash, BlockNumber, FlatPieces, LastArchivedBlock, PieceArray,
3939
RecordsRoot, RootBlock, RECORDED_HISTORY_SEGMENT_SIZE, RECORD_SIZE,
4040
};
4141

@@ -749,20 +749,20 @@ impl Archiver {
749749
// Combine data and parity records back into flat vector of pieces along with corresponding
750750
// witnesses (Merkle proofs) created above.
751751
pieces
752-
.as_pieces_mut()
752+
.iter_mut()
753753
.enumerate()
754754
.zip(
755755
record_shards
756756
.as_bytes()
757757
.as_ref()
758758
.chunks_exact(RECORD_SIZE as usize),
759759
)
760-
.for_each(|((position, mut piece), shard_chunk)| {
761-
let (mut record, mut witness) = piece.split_mut();
760+
.for_each(|((position, piece), shard_chunk)| {
761+
let (record, witness) = piece.split_mut();
762762

763-
record.as_mut().copy_from_slice(shard_chunk);
763+
record.copy_from_slice(shard_chunk);
764764
// TODO: Consider batch witness creation for improved performance
765-
witness.as_mut().copy_from_slice(
765+
witness.copy_from_slice(
766766
&self
767767
.kzg
768768
.create_witness(&polynomial, position as u32)
@@ -799,18 +799,18 @@ impl Archiver {
799799
pub fn is_piece_valid(
800800
kzg: &Kzg,
801801
num_pieces_in_segment: usize,
802-
piece: PieceRef<'_>,
802+
piece: &PieceArray,
803803
commitment: RecordsRoot,
804804
position: u32,
805805
) -> bool {
806806
let (record, witness) = piece.split();
807-
let witness = match Witness::try_from_bytes(&witness) {
807+
let witness = match Witness::try_from_bytes(witness) {
808808
Ok(witness) => witness,
809809
_ => {
810810
return false;
811811
}
812812
};
813-
let leaf_hash = blake2b_256_254_hash_to_scalar(&record);
813+
let leaf_hash = blake2b_256_254_hash_to_scalar(record.as_ref());
814814

815815
kzg.verify(
816816
&commitment,

crates/subspace-archiving/src/piece_reconstructor.rs

+14-24
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,10 @@ impl PiecesReconstructor {
105105
//TODO: reuse already present commitments from segment_pieces, so we don't re-derive what
106106
// we already have
107107
reconstructed_record_shards
108-
.as_pieces_mut()
108+
.iter_mut()
109109
.zip(record_commitments.iter_mut())
110110
.zip(shards)
111-
.for_each(|((mut piece, polynomial_data), record)| {
111+
.for_each(|((piece, polynomial_data), record)| {
112112
let record =
113113
record.expect("Reconstruction just happened and all records are present; qed");
114114
let record = record.flatten();
@@ -133,20 +133,17 @@ impl PiecesReconstructor {
133133
) -> Result<FlatPieces, ReconstructorError> {
134134
let (mut pieces, polynomial) = self.reconstruct_shards(segment_pieces)?;
135135

136-
pieces
137-
.as_pieces_mut()
138-
.enumerate()
139-
.for_each(|(position, mut piece)| {
140-
piece.witness_mut().as_mut().copy_from_slice(
141-
&self
142-
.kzg
143-
.create_witness(&polynomial, position as u32)
144-
// TODO: Update this proof here and in other places, we don't use Merkle
145-
// trees anymore
146-
.expect("We use the same indexes as during Merkle tree creation; qed")
147-
.to_bytes(),
148-
);
149-
});
136+
pieces.iter_mut().enumerate().for_each(|(position, piece)| {
137+
piece.witness_mut().as_mut().copy_from_slice(
138+
&self
139+
.kzg
140+
.create_witness(&polynomial, position as u32)
141+
// TODO: Update this proof here and in other places, we don't use Merkle
142+
// trees anymore
143+
.expect("We use the same indexes as during Merkle tree creation; qed")
144+
.to_bytes(),
145+
);
146+
});
150147

151148
Ok(pieces)
152149
}
@@ -164,14 +161,7 @@ impl PiecesReconstructor {
164161
return Err(ReconstructorError::IncorrectPiecePosition);
165162
}
166163

167-
let mut piece = Piece::from(
168-
reconstructed_records
169-
.as_pieces()
170-
.nth(piece_position)
171-
.expect(
172-
"Piece exists at the position within segment after successful reconstruction; qed",
173-
),
174-
);
164+
let mut piece = Piece::from(reconstructed_records[piece_position]);
175165

176166
piece.witness_mut().as_mut().copy_from_slice(
177167
&self

crates/subspace-archiving/src/reconstructor.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ impl Reconstructor {
117117
.take(self.reed_solomon.data_shard_count())
118118
.all(|maybe_piece| {
119119
if let Some(piece) = maybe_piece {
120-
segment_data.extend_from_slice(&piece.record());
120+
segment_data.extend_from_slice(piece.record().as_ref());
121121
true
122122
} else {
123123
false

0 commit comments

Comments
 (0)