@@ -22,7 +22,7 @@ impl<N: Network> FromBytes for Block<N> {
2222 // Read the version.
2323 let version = u8:: read_le ( & mut reader) ?;
2424 // Ensure the version is valid.
25- if version != 1 {
25+ if ! [ 1 , 2 ] . contains ( & version ) {
2626 return Err ( error ( "Invalid block version" ) ) ;
2727 }
2828
@@ -42,32 +42,78 @@ impl<N: Network> FromBytes for Block<N> {
4242 // Read the solutions.
4343 let solutions: Solutions < N > = FromBytes :: read_le ( & mut reader) ?;
4444
45- // Read the number of aborted solution IDs.
46- let num_aborted_solutions = u32:: read_le ( & mut reader) ?;
47- // Ensure the number of aborted solutions IDs is within bounds (this is an early safety check).
48- if num_aborted_solutions as usize > Solutions :: < N > :: max_aborted_solutions ( ) . map_err ( error) ? {
49- return Err ( error ( "Invalid number of aborted solutions IDs in the block" ) ) ;
50- }
51- // Read the aborted solution IDs.
52- let mut aborted_solution_ids = Vec :: with_capacity ( num_aborted_solutions as usize ) ;
53- for _ in 0 ..num_aborted_solutions {
54- aborted_solution_ids. push ( FromBytes :: read_le ( & mut reader) ?) ;
55- }
45+ let ( prior_solution_transmission_ids, aborted_solution_transmission_ids, aborted_solution_ids) = if version >= 2
46+ {
47+ // Read the number of prior solution transmission IDs.
48+ let num_prior_solutions = u32:: read_le ( & mut reader) ?; // TODO: what is a sane bound on this value?
49+ // Read the prior solution transmission IDs.
50+ let mut prior_solution_transmission_ids = Vec :: with_capacity ( num_prior_solutions as usize ) ;
51+ for _ in 0 ..num_prior_solutions {
52+ prior_solution_transmission_ids. push ( FromBytes :: read_le ( & mut reader) ?) ;
53+ }
54+ // Read the number of aborted solution transmission IDs.
55+ let num_aborted_solutions = u32:: read_le ( & mut reader) ?;
56+ if num_aborted_solutions as usize > Solutions :: < N > :: max_aborted_solutions ( ) . map_err ( error) ? {
57+ return Err ( error ( "Invalid number of aborted solutions IDs in the block" ) ) ;
58+ }
59+ // Read the aborted solution transmission IDs.
60+ let mut aborted_solution_transmission_ids = Vec :: with_capacity ( num_aborted_solutions as usize ) ;
61+ for _ in 0 ..num_aborted_solutions {
62+ aborted_solution_transmission_ids. push ( FromBytes :: read_le ( & mut reader) ?) ;
63+ }
64+ ( Some ( prior_solution_transmission_ids) , Some ( aborted_solution_transmission_ids) , vec ! [ ] )
65+ } else {
66+ // Read the number of aborted solution IDs.
67+ let num_aborted_solutions = u32:: read_le ( & mut reader) ?;
68+ // Ensure the number of aborted solutions IDs is within bounds (this is an early safety check).
69+ if num_aborted_solutions as usize > Solutions :: < N > :: max_aborted_solutions ( ) . map_err ( error) ? {
70+ return Err ( error ( "Invalid number of aborted solutions IDs in the block" ) ) ;
71+ }
72+ // Read the aborted solution IDs.
73+ let mut aborted_solution_ids = Vec :: with_capacity ( num_aborted_solutions as usize ) ;
74+ for _ in 0 ..num_aborted_solutions {
75+ aborted_solution_ids. push ( FromBytes :: read_le ( & mut reader) ?) ;
76+ }
77+ ( None , None , aborted_solution_ids)
78+ } ;
5679
5780 // Read the transactions.
5881 let transactions = FromBytes :: read_le ( & mut reader) ?;
5982
60- // Read the number of aborted transaction IDs.
61- let num_aborted_transactions = u32:: read_le ( & mut reader) ?;
62- // Ensure the number of aborted transaction IDs is within bounds (this is an early safety check).
63- if num_aborted_transactions as usize > Transactions :: < N > :: max_aborted_transactions ( ) . map_err ( error) ? {
64- return Err ( error ( "Invalid number of aborted transaction IDs in the block" ) ) ;
65- }
66- // Read the aborted transaction IDs.
67- let mut aborted_transaction_ids = Vec :: with_capacity ( num_aborted_transactions as usize ) ;
68- for _ in 0 ..num_aborted_transactions {
69- aborted_transaction_ids. push ( FromBytes :: read_le ( & mut reader) ?) ;
70- }
83+ let ( prior_transaction_transmission_ids, aborted_transaction_transmission_ids, aborted_transaction_ids) =
84+ if version >= 2 {
85+ // Read the number of prior transaction transmission IDs.
86+ let num_prior_transactions = u32:: read_le ( & mut reader) ?; // TODO: what is a sane bound on this value?
87+ // Read the prior transaction transmission IDs.
88+ let mut prior_transaction_transmission_ids = Vec :: with_capacity ( num_prior_transactions as usize ) ;
89+ for _ in 0 ..num_prior_transactions {
90+ prior_transaction_transmission_ids. push ( FromBytes :: read_le ( & mut reader) ?) ;
91+ }
92+ // Read the number of aborted transaction transmission IDs.
93+ let num_aborted_transactions = u32:: read_le ( & mut reader) ?;
94+ if num_aborted_transactions as usize > Transactions :: < N > :: max_aborted_transactions ( ) . map_err ( error) ? {
95+ return Err ( error ( "Invalid number of aborted transaction IDs in the block" ) ) ;
96+ }
97+ // Read the aborted transaction transmission IDs.
98+ let mut aborted_transaction_transmission_ids = Vec :: with_capacity ( num_aborted_transactions as usize ) ;
99+ for _ in 0 ..num_aborted_transactions {
100+ aborted_transaction_transmission_ids. push ( FromBytes :: read_le ( & mut reader) ?) ;
101+ }
102+ ( Some ( prior_transaction_transmission_ids) , Some ( aborted_transaction_transmission_ids) , vec ! [ ] )
103+ } else {
104+ // Read the number of aborted transaction IDs.
105+ let num_aborted_transactions = u32:: read_le ( & mut reader) ?;
106+ // Ensure the number of aborted transaction IDs is within bounds (this is an early safety check).
107+ if num_aborted_transactions as usize > Transactions :: < N > :: max_aborted_transactions ( ) . map_err ( error) ? {
108+ return Err ( error ( "Invalid number of aborted transaction IDs in the block" ) ) ;
109+ }
110+ // Read the aborted transaction IDs.
111+ let mut aborted_transaction_ids = Vec :: with_capacity ( num_aborted_transactions as usize ) ;
112+ for _ in 0 ..num_aborted_transactions {
113+ aborted_transaction_ids. push ( FromBytes :: read_le ( & mut reader) ?) ;
114+ }
115+ ( None , None , aborted_transaction_ids)
116+ } ;
71117
72118 // Construct the block.
73119 let block = Self :: from (
@@ -76,8 +122,12 @@ impl<N: Network> FromBytes for Block<N> {
76122 authority,
77123 ratifications,
78124 solutions,
125+ prior_solution_transmission_ids,
126+ aborted_solution_transmission_ids,
79127 aborted_solution_ids,
80128 transactions,
129+ prior_transaction_transmission_ids,
130+ aborted_transaction_transmission_ids,
81131 aborted_transaction_ids,
82132 )
83133 . map_err ( error) ?;
@@ -95,7 +145,9 @@ impl<N: Network> ToBytes for Block<N> {
95145 #[ inline]
96146 fn write_le < W : Write > ( & self , mut writer : W ) -> IoResult < ( ) > {
97147 // Write the version.
98- 1u8 . write_le ( & mut writer) ?;
148+ let version =
149+ if N :: CONSENSUS_VERSION ( self . height ( ) ) . map_err ( error) ? >= ConsensusVersion :: V10 { 2u8 } else { 1 } ;
150+ version. write_le ( & mut writer) ?;
99151
100152 // Write the block hash.
101153 self . block_hash . write_le ( & mut writer) ?;
@@ -113,16 +165,57 @@ impl<N: Network> ToBytes for Block<N> {
113165 // Write the solutions.
114166 self . solutions . write_le ( & mut writer) ?;
115167
116- // Write the aborted solution IDs.
117- ( u32:: try_from ( self . aborted_solution_ids . len ( ) ) . map_err ( error) ) ?. write_le ( & mut writer) ?;
118- self . aborted_solution_ids . write_le ( & mut writer) ?;
168+ match version {
169+ 1 => {
170+ // Write the aborted solution IDs.
171+ ( u32:: try_from ( self . aborted_solution_ids . len ( ) ) . map_err ( error) ) ?. write_le ( & mut writer) ?;
172+ self . aborted_solution_ids . write_le ( & mut writer) ?;
173+ }
174+ _ => {
175+ // Write the prior solution transmission ids.
176+ let prior_solution_transmission_ids = self
177+ . prior_solution_transmission_ids
178+ . as_ref ( )
179+ . ok_or ( error ( "missing prior_solution_transmission_ids" ) ) ?;
180+ ( u32:: try_from ( prior_solution_transmission_ids. len ( ) ) . map_err ( error) ) ?. write_le ( & mut writer) ?;
181+ prior_solution_transmission_ids. write_le ( & mut writer) ?;
182+ // Write the aborted solution transmission ids.
183+ let aborted_solution_transmission_ids = self
184+ . aborted_solution_transmission_ids
185+ . as_ref ( )
186+ . ok_or ( error ( "missing aborted_solution_transmission_ids" ) ) ?;
187+ ( u32:: try_from ( aborted_solution_transmission_ids. len ( ) ) . map_err ( error) ) ?. write_le ( & mut writer) ?;
188+ aborted_solution_transmission_ids. write_le ( & mut writer) ?;
189+ }
190+ }
119191
120192 // Write the transactions.
121193 self . transactions . write_le ( & mut writer) ?;
122194
123- // Write the aborted transaction IDs.
124- ( u32:: try_from ( self . aborted_transaction_ids . len ( ) ) . map_err ( error) ) ?. write_le ( & mut writer) ?;
125- self . aborted_transaction_ids . write_le ( & mut writer)
195+ match version {
196+ 1 => {
197+ // Write the aborted transaction ids.
198+ ( u32:: try_from ( self . aborted_transaction_ids . len ( ) ) . map_err ( error) ) ?. write_le ( & mut writer) ?;
199+ self . aborted_transaction_ids . write_le ( & mut writer) ?;
200+ }
201+ _ => {
202+ // Write the prior transaction transmission ids.
203+ let prior_transaction_transmission_ids = self
204+ . prior_transaction_transmission_ids
205+ . as_ref ( )
206+ . ok_or ( error ( "missing prior_transaction_transmission_ids" ) ) ?;
207+ ( u32:: try_from ( prior_transaction_transmission_ids. len ( ) ) . map_err ( error) ) ?. write_le ( & mut writer) ?;
208+ prior_transaction_transmission_ids. write_le ( & mut writer) ?;
209+ // Write the aborted transaction transmission ids.
210+ let aborted_transaction_transmission_ids = self
211+ . aborted_transaction_transmission_ids
212+ . as_ref ( )
213+ . ok_or ( error ( "missing aborted_transaction_transmission_ids" ) ) ?;
214+ ( u32:: try_from ( aborted_transaction_transmission_ids. len ( ) ) . map_err ( error) ) ?. write_le ( & mut writer) ?;
215+ aborted_transaction_transmission_ids. write_le ( & mut writer) ?;
216+ }
217+ }
218+ Ok ( ( ) )
126219 }
127220}
128221
@@ -138,6 +231,7 @@ mod tests {
138231 let rng = & mut TestRng :: default ( ) ;
139232
140233 for expected in [ crate :: test_helpers:: sample_genesis_block ( rng) ] . into_iter ( ) {
234+ // todo: sample compact too for the Block tests
141235 // Check the byte representation.
142236 let expected_bytes = expected. to_bytes_le ( ) ?;
143237 assert_eq ! ( expected, Block :: read_le( & expected_bytes[ ..] ) ?) ;
0 commit comments