@@ -241,30 +241,36 @@ impl From<bitcoinconsensus::Error> for Error {
241
241
Error :: BitcoinConsensus ( err)
242
242
}
243
243
}
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; }
247
250
248
251
let neg = n < 0 ;
249
252
250
253
let mut abs = if neg { -n } else { n } as usize ;
251
- let mut v = vec ! [ ] ;
252
254
while abs > 0xFF {
253
- v. push ( ( abs & 0xFF ) as u8 ) ;
255
+ out[ len] = ( abs & 0xFF ) as u8 ;
256
+ len += 1 ;
254
257
abs >>= 8 ;
255
258
}
256
259
// If the number's value causes the sign bit to be set, we need an extra
257
260
// byte to get the correct value and correct sign bit
258
261
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 ;
261
266
}
262
267
// Otherwise we just set the sign bit ourselves
263
268
else {
264
269
abs |= if neg { 0x80 } else { 0 } ;
265
- v. push ( abs as u8 ) ;
270
+ out[ len] = abs as u8 ;
271
+ len += 1 ;
266
272
}
267
- v
273
+ len
268
274
}
269
275
270
276
/// Helper to decode an integer in script format
@@ -908,7 +914,9 @@ impl Builder {
908
914
/// Adds instructions to push an integer onto the stack, using the explicit
909
915
/// encoding regardless of the availability of dedicated opcodes.
910
916
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] )
912
920
}
913
921
914
922
/// Adds instructions to push some arbitrary data onto the stack.
@@ -1106,7 +1114,7 @@ mod test {
1106
1114
use core:: str:: FromStr ;
1107
1115
1108
1116
use super :: * ;
1109
- use super :: build_scriptint ;
1117
+ use super :: write_scriptint ;
1110
1118
1111
1119
use crate :: hashes:: hex:: { FromHex , ToHex } ;
1112
1120
use crate :: consensus:: encode:: { deserialize, serialize} ;
@@ -1287,13 +1295,23 @@ mod test {
1287
1295
1288
1296
#[ test]
1289
1297
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
+
1290
1305
assert_eq ! ( build_scriptint( -1 ) , vec![ 0x81 ] ) ;
1291
1306
assert_eq ! ( build_scriptint( 255 ) , vec![ 255 , 0 ] ) ;
1292
1307
assert_eq ! ( build_scriptint( 256 ) , vec![ 0 , 1 ] ) ;
1293
1308
assert_eq ! ( build_scriptint( 257 ) , vec![ 1 , 1 ] ) ;
1294
1309
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 ( ) {
1297
1315
assert_eq ! ( Ok ( i) , read_scriptint( & build_scriptint( i) ) ) ;
1298
1316
assert_eq ! ( Ok ( -i) , read_scriptint( & build_scriptint( -i) ) ) ;
1299
1317
}
0 commit comments