4
4
protocol:: MAX_CRDS_OBJECT_SIZE ,
5
5
} ,
6
6
bincode:: serialized_size,
7
- bv :: BitVec ,
7
+ bitvec :: prelude :: BitVec ,
8
8
flate2:: { Compress , Compression , Decompress , FlushCompress , FlushDecompress } ,
9
9
solana_sanitize:: { Sanitize , SanitizeError } ,
10
10
solana_sdk:: { clock:: Slot , pubkey:: Pubkey } ,
@@ -81,30 +81,44 @@ impl std::convert::From<flate2::DecompressError> for Error {
81
81
}
82
82
83
83
impl Flate2 {
84
- fn deflate ( mut unc : Uncompressed ) -> Result < Self > {
85
- let mut compressed = Vec :: with_capacity ( unc. slots . block_capacity ( ) ) ;
84
+ fn deflate ( unc : Uncompressed ) -> Result < Self > {
85
+ // View into the slots array as raw bytes
86
+ let bits = unc. slots . as_raw_slice ( ) ;
87
+ // Assume compressed version will be smaller than the original
88
+ let mut compressed = Vec :: with_capacity ( bits. len ( ) ) ;
89
+ // Perform compression and check status to make sure everything fits
86
90
let mut compressor = Compress :: new ( Compression :: best ( ) , false ) ;
87
- let first_slot = unc . first_slot ;
88
- let num = unc . num ;
89
- unc . slots . shrink_to_fit ( ) ;
90
- let bits = unc . slots . into_boxed_slice ( ) ;
91
- compressor . compress_vec ( & bits , & mut compressed , FlushCompress :: Finish ) ? ;
91
+ let status = compressor . compress_vec ( bits , & mut compressed , FlushCompress :: Finish ) ? ;
92
+ if status != flate2 :: Status :: StreamEnd {
93
+ return Err ( Error :: CompressError ) ;
94
+ }
95
+
92
96
let rv = Self {
93
- first_slot,
94
- num,
97
+ first_slot : unc . first_slot ,
98
+ num : unc . num ,
95
99
compressed,
96
100
} ;
97
101
Ok ( rv)
98
102
}
103
+
99
104
pub fn inflate ( & self ) -> Result < Uncompressed > {
100
105
//add some head room for the decompressor which might spill more bits
101
106
let mut uncompressed = Vec :: with_capacity ( 32 + ( self . num + 4 ) / 8 ) ;
107
+ // Perform the actual decompression and check that the result fits into provided buffer
102
108
let mut decompress = Decompress :: new ( false ) ;
103
- decompress. decompress_vec ( & self . compressed , & mut uncompressed, FlushDecompress :: Finish ) ?;
109
+ let status = decompress. decompress_vec (
110
+ & self . compressed ,
111
+ & mut uncompressed,
112
+ FlushDecompress :: Finish ,
113
+ ) ?;
114
+ if status != flate2:: Status :: StreamEnd {
115
+ return Err ( Error :: DecompressError ) ;
116
+ }
117
+
104
118
Ok ( Uncompressed {
105
119
first_slot : self . first_slot ,
106
120
num : self . num ,
107
- slots : BitVec :: from_bits ( & uncompressed) ,
121
+ slots : BitVec :: from_vec ( uncompressed) ,
108
122
} )
109
123
}
110
124
}
@@ -114,7 +128,7 @@ impl Uncompressed {
114
128
Self {
115
129
num : 0 ,
116
130
first_slot : 0 ,
117
- slots : BitVec :: new_fill ( false , 8 * max_size as u64 ) ,
131
+ slots : BitVec :: repeat ( false , 8 * max_size) ,
118
132
}
119
133
}
120
134
pub fn to_slots ( & self , min_slot : Slot ) -> Vec < Slot > {
@@ -125,10 +139,10 @@ impl Uncompressed {
125
139
( min_slot - self . first_slot ) as usize
126
140
} ;
127
141
for i in start..self . num {
128
- if i >= self . slots . len ( ) as usize {
142
+ if i >= self . slots . len ( ) {
129
143
break ;
130
144
}
131
- if self . slots . get ( i as u64 ) {
145
+ if * self . slots . get ( i) . expect ( "slot index should be in bounds" ) {
132
146
rv. push ( self . first_slot + i as Slot ) ;
133
147
}
134
148
}
@@ -145,11 +159,12 @@ impl Uncompressed {
145
159
if * s < self . first_slot {
146
160
return i;
147
161
}
148
- if * s - self . first_slot >= self . slots . len ( ) {
162
+ let offset = ( * s - self . first_slot ) as usize ;
163
+ if offset >= self . slots . len ( ) {
149
164
return i;
150
165
}
151
- self . slots . set ( * s - self . first_slot , true ) ;
152
- self . num = std:: cmp:: max ( self . num , 1 + ( * s - self . first_slot ) as usize ) ;
166
+ self . slots . set ( offset , true ) ;
167
+ self . num = std:: cmp:: max ( self . num , 1 + offset ) ;
153
168
}
154
169
slots. len ( )
155
170
}
@@ -422,7 +437,7 @@ mod tests {
422
437
assert_eq ! ( o. sanitize( ) , Err ( SanitizeError :: ValueOutOfBounds ) ) ;
423
438
424
439
let mut o = slots. clone ( ) ;
425
- o. slots = BitVec :: new_fill ( false , 7 ) ; // Length not a multiple of 8
440
+ o. slots = BitVec :: repeat ( false , 7 ) ; // Length not a multiple of 8
426
441
assert_eq ! ( o. sanitize( ) , Err ( SanitizeError :: ValueOutOfBounds ) ) ;
427
442
428
443
let mut o = slots. clone ( ) ;
0 commit comments