@@ -44,6 +44,7 @@ impl Tx {
4444 tx_body. push ( 0xFF ) ;
4545 // Zero value
4646 tx_body. extend_from_slice ( & [ 0u8 ; 8 ] ) ;
47+
4748 tx_body. extend_from_slice ( & self . public_key . to_bytes ( ) ) ;
4849
4950 // Add the size of decoded bytes to the beginning.
@@ -62,91 +63,83 @@ impl Tx {
6263 /// - Invalid vote tag value.
6364 /// - Invalid public key.
6465 #[ allow( clippy:: indexing_slicing) ]
65- pub fn from_bytes ( mut bytes : & [ u8 ] ) -> anyhow:: Result < Self > {
66+ pub fn from_bytes < R : Read > ( reader : & mut R ) -> anyhow:: Result < Self > {
6667 let mut u8_buf = [ 0u8 ; 1 ] ;
6768 let mut u32_buf = [ 0u8 ; 4 ] ;
6869 let mut u64_buf = [ 0u8 ; 8 ] ;
6970 let mut u256_buf = [ 0u8 ; 32 ] ;
7071
71- // Read tx size
72- bytes. read_exact ( & mut u32_buf) ?;
73- let tx_size = u32:: from_be_bytes ( u32_buf) ;
74- ensure ! (
75- tx_size as usize == bytes. len( ) ,
76- "Invalid tx size, expected: {tx_size}, provided: {0}." ,
77- bytes. len( )
78- ) ;
72+ // Skip tx size field
73+ reader. read_exact ( & mut u32_buf) ?;
7974
80- bytes . read_exact ( & mut u8_buf) ?;
75+ reader . read_exact ( & mut u8_buf) ?;
8176 ensure ! (
8277 u8_buf[ 0 ] == 0 ,
8378 "Invalid padding tag field value, must be equals to `0`, provided: {0}." ,
8479 u8_buf[ 0 ]
8580 ) ;
8681
87- bytes . read_exact ( & mut u8_buf) ?;
82+ reader . read_exact ( & mut u8_buf) ?;
8883 ensure ! (
8984 u8_buf[ 0 ] == 11 ,
9085 "Invalid fragment tag field value, must be equals to `11`, provided: {0}." ,
9186 u8_buf[ 0 ]
9287 ) ;
9388
94- bytes . read_exact ( & mut u256_buf) ?;
89+ reader . read_exact ( & mut u256_buf) ?;
9590 let vote_plan_id = u256_buf;
9691
97- bytes . read_exact ( & mut u8_buf) ?;
92+ reader . read_exact ( & mut u8_buf) ?;
9893 let proposal_index = u8_buf[ 0 ] ;
9994
100- bytes . read_exact ( & mut u8_buf) ?;
95+ reader . read_exact ( & mut u8_buf) ?;
10196 let vote = match u8_buf[ 0 ] {
10297 1 => {
103- bytes . read_exact ( & mut u8_buf) ?;
98+ reader . read_exact ( & mut u8_buf) ?;
10499 Vote :: Public ( u8_buf[ 0 ] )
105100 } ,
106101 2 => {
107- bytes . read_exact ( & mut u8_buf) ?;
108- let vote = EncryptedVote :: from_bytes ( bytes , u8_buf[ 0 ] . into ( ) )
102+ reader . read_exact ( & mut u8_buf) ?;
103+ let vote = EncryptedVote :: from_bytes ( reader , u8_buf[ 0 ] . into ( ) )
109104 . map_err ( |e| anyhow ! ( "Invalid encrypted vote, error: {e}." ) ) ?;
110- bytes = & bytes[ vote. bytes_size ( ) ..] ;
111105
112- bytes . read_exact ( & mut u8_buf) ?;
113- let proof = VoterProof :: from_bytes ( bytes , u8_buf[ 0 ] . into ( ) )
106+ reader . read_exact ( & mut u8_buf) ?;
107+ let proof = VoterProof :: from_bytes ( reader , u8_buf[ 0 ] . into ( ) )
114108 . map_err ( |e| anyhow ! ( "Invalid voter proof, error: {e}." ) ) ?;
115- bytes = & bytes[ proof. bytes_size ( ) ..] ;
116109
117110 Vote :: Private ( vote, proof)
118111 } ,
119112 tag => bail ! ( "Invalid vote tag value, must be equals to `0` or `1`, provided: {tag}" ) ,
120113 } ;
121114
122115 // skip block date (epoch and slot)
123- bytes . read_exact ( & mut u64_buf) ?;
116+ reader . read_exact ( & mut u64_buf) ?;
124117
125- bytes . read_exact ( & mut u8_buf) ?;
118+ reader . read_exact ( & mut u8_buf) ?;
126119 ensure ! (
127120 u8_buf[ 0 ] == 1 ,
128121 "Invalid number of inputs, expected: `1`, provided: {0}" ,
129122 u8_buf[ 0 ]
130123 ) ;
131124
132- bytes . read_exact ( & mut u8_buf) ?;
125+ reader . read_exact ( & mut u8_buf) ?;
133126 ensure ! (
134127 u8_buf[ 0 ] == 0 ,
135128 "Invalid number of outputs, expected: `0`, provided: {0}" ,
136129 u8_buf[ 0 ]
137130 ) ;
138131
139- bytes . read_exact ( & mut u8_buf) ?;
132+ reader . read_exact ( & mut u8_buf) ?;
140133 ensure ! (
141134 u8_buf[ 0 ] == 0xFF ,
142135 "Invalid input tag, expected: `255`, provided: {0}" ,
143136 u8_buf[ 0 ]
144137 ) ;
145138
146139 // skip value
147- bytes . read_exact ( & mut u64_buf) ?;
140+ reader . read_exact ( & mut u64_buf) ?;
148141
149- bytes . read_exact ( & mut u256_buf) ?;
142+ reader . read_exact ( & mut u256_buf) ?;
150143 let public_key = PublicKey :: from_bytes ( & u256_buf)
151144 . map_err ( |e| anyhow ! ( "Invalid public key, error: {e}." ) ) ?;
152145
@@ -161,6 +154,8 @@ impl Tx {
161154
162155#[ cfg( test) ]
163156mod tests {
157+ use std:: io:: Cursor ;
158+
164159 use proptest:: prelude:: { any, any_with, Arbitrary , BoxedStrategy , Strategy } ;
165160 use test_strategy:: proptest;
166161
@@ -211,7 +206,12 @@ mod tests {
211206 #[ allow( clippy:: indexing_slicing) ]
212207 fn tx_to_bytes_from_bytes_test ( t1 : Tx ) {
213208 let bytes = t1. to_bytes ( ) ;
214- let t2 = Tx :: from_bytes ( & bytes) . unwrap ( ) ;
209+
210+ // verify correctness serializing tx size field
211+ let size = u32:: from_be_bytes ( bytes[ 0 ..4 ] . try_into ( ) . unwrap ( ) ) ;
212+ assert_eq ! ( size as usize , bytes. len( ) - 4 ) ;
213+
214+ let t2 = Tx :: from_bytes ( & mut Cursor :: new ( bytes) ) . unwrap ( ) ;
215215 assert_eq ! ( t1, t2) ;
216216 }
217217}
0 commit comments