@@ -241,30 +241,36 @@ impl From<bitcoinconsensus::Error> for Error {
241241 Error :: BitcoinConsensus ( err)
242242 }
243243}
244- /// Helper to encode an integer in script format
245- fn build_scriptint ( n : i64 ) -> Vec < u8 > {
246- if n == 0 { return vec ! [ ] }
244+
245+ /// Helper to encode an integer in script format.
246+ /// Writes bytes into the buffer and returns the number of bytes written.
247+ fn write_scriptint ( out : & mut [ u8 ; 8 ] , n : i64 ) -> usize {
248+ let mut len = 0 ;
249+ if n == 0 { return len; }
247250
248251 let neg = n < 0 ;
249252
250253 let mut abs = if neg { -n } else { n } as usize ;
251- let mut v = vec ! [ ] ;
252254 while abs > 0xFF {
253- v. push ( ( abs & 0xFF ) as u8 ) ;
255+ out[ len] = ( abs & 0xFF ) as u8 ;
256+ len += 1 ;
254257 abs >>= 8 ;
255258 }
256259 // If the number's value causes the sign bit to be set, we need an extra
257260 // byte to get the correct value and correct sign bit
258261 if abs & 0x80 != 0 {
259- v. push ( abs as u8 ) ;
260- v. push ( if neg { 0x80u8 } else { 0u8 } ) ;
262+ out[ len] = abs as u8 ;
263+ len += 1 ;
264+ out[ len] = if neg { 0x80u8 } else { 0u8 } ;
265+ len += 1 ;
261266 }
262267 // Otherwise we just set the sign bit ourselves
263268 else {
264269 abs |= if neg { 0x80 } else { 0 } ;
265- v. push ( abs as u8 ) ;
270+ out[ len] = abs as u8 ;
271+ len += 1 ;
266272 }
267- v
273+ len
268274}
269275
270276/// Helper to decode an integer in script format
@@ -908,7 +914,9 @@ impl Builder {
908914 /// Adds instructions to push an integer onto the stack, using the explicit
909915 /// encoding regardless of the availability of dedicated opcodes.
910916 pub fn push_scriptint ( self , data : i64 ) -> Builder {
911- self . push_slice ( & build_scriptint ( data) )
917+ let mut buf = [ 0u8 ; 8 ] ;
918+ let len = write_scriptint ( & mut buf, data) ;
919+ self . push_slice ( & buf[ ..len] )
912920 }
913921
914922 /// Adds instructions to push some arbitrary data onto the stack.
@@ -1106,7 +1114,7 @@ mod test {
11061114 use core:: str:: FromStr ;
11071115
11081116 use super :: * ;
1109- use super :: build_scriptint ;
1117+ use super :: write_scriptint ;
11101118
11111119 use crate :: hashes:: hex:: { FromHex , ToHex } ;
11121120 use crate :: consensus:: encode:: { deserialize, serialize} ;
@@ -1287,13 +1295,23 @@ mod test {
12871295
12881296 #[ test]
12891297 fn scriptint_round_trip ( ) {
1298+ fn build_scriptint ( n : i64 ) -> Vec < u8 > {
1299+ let mut buf = [ 0u8 ; 8 ] ;
1300+ let len = write_scriptint ( & mut buf, n) ;
1301+ assert ! ( len <= 8 ) ;
1302+ buf[ ..len] . to_vec ( )
1303+ }
1304+
12901305 assert_eq ! ( build_scriptint( -1 ) , vec![ 0x81 ] ) ;
12911306 assert_eq ! ( build_scriptint( 255 ) , vec![ 255 , 0 ] ) ;
12921307 assert_eq ! ( build_scriptint( 256 ) , vec![ 0 , 1 ] ) ;
12931308 assert_eq ! ( build_scriptint( 257 ) , vec![ 1 , 1 ] ) ;
12941309 assert_eq ! ( build_scriptint( 511 ) , vec![ 255 , 1 ] ) ;
1295- for & i in [ 10 , 100 , 255 , 256 , 1000 , 10000 , 25000 , 200000 , 5000000 , 1000000000 ,
1296- ( 1 << 31 ) - 1 , -( ( 1 << 31 ) - 1 ) ] . iter ( ) {
1310+ let test_vectors = [
1311+ 10 , 100 , 255 , 256 , 1000 , 10000 , 25000 , 200000 , 5000000 , 1000000000 ,
1312+ ( 1 << 31 ) - 1 , -( ( 1 << 31 ) - 1 ) ,
1313+ ] ;
1314+ for & i in test_vectors. iter ( ) {
12971315 assert_eq ! ( Ok ( i) , read_scriptint( & build_scriptint( i) ) ) ;
12981316 assert_eq ! ( Ok ( -i) , read_scriptint( & build_scriptint( -i) ) ) ;
12991317 }
0 commit comments