8
8
// licenses.
9
9
10
10
use bitcoin:: amount:: Amount ;
11
- use bitcoin:: transaction:: { Transaction , TxOut } ;
12
- use bitcoin:: script:: ScriptBuf ;
13
- use bitcoin:: consensus:: Encodable ;
14
11
use bitcoin:: consensus:: encode:: VarInt ;
12
+ use bitcoin:: consensus:: Encodable ;
13
+ use bitcoin:: script:: ScriptBuf ;
14
+ use bitcoin:: transaction:: { Transaction , TxOut } ;
15
15
16
16
#[ allow( unused_imports) ]
17
17
use crate :: prelude:: * ;
18
18
19
19
use crate :: io_extras:: sink;
20
20
use core:: cmp:: Ordering ;
21
21
22
- pub fn sort_outputs < T , C : Fn ( & T , & T ) -> Ordering > ( outputs : & mut Vec < ( TxOut , T ) > , tie_breaker : C ) {
22
+ pub fn sort_outputs < T , C : Fn ( & T , & T ) -> Ordering > ( outputs : & mut Vec < ( TxOut , T ) > , tie_breaker : C ) {
23
23
outputs. sort_unstable_by ( |a, b| {
24
24
a. 0 . value . cmp ( & b. 0 . value ) . then_with ( || {
25
- a. 0 . script_pubkey [ ..] . cmp ( & b. 0 . script_pubkey [ ..] ) . then_with ( || {
26
- tie_breaker ( & a. 1 , & b. 1 )
27
- } )
25
+ a. 0 . script_pubkey [ ..] . cmp ( & b. 0 . script_pubkey [ ..] ) . then_with ( || tie_breaker ( & a. 1 , & b. 1 ) )
28
26
} )
29
27
} ) ;
30
28
}
@@ -34,22 +32,26 @@ pub fn sort_outputs<T, C : Fn(&T, &T) -> Ordering>(outputs: &mut Vec<(TxOut, T)>
34
32
/// Assumes at least one input will have a witness (ie spends a segwit output).
35
33
/// Returns an Err(()) if the requested feerate cannot be met.
36
34
/// Returns the expected maximum weight of the fully signed transaction on success.
37
- pub ( crate ) fn maybe_add_change_output ( tx : & mut Transaction , input_value : Amount , witness_max_weight : u64 , feerate_sat_per_1000_weight : u32 , change_destination_script : ScriptBuf ) -> Result < u64 , ( ) > {
38
- if input_value > Amount :: MAX_MONEY { return Err ( ( ) ) ; }
35
+ pub ( crate ) fn maybe_add_change_output (
36
+ tx : & mut Transaction , input_value : Amount , witness_max_weight : u64 ,
37
+ feerate_sat_per_1000_weight : u32 , change_destination_script : ScriptBuf ,
38
+ ) -> Result < u64 , ( ) > {
39
+ if input_value > Amount :: MAX_MONEY {
40
+ return Err ( ( ) ) ;
41
+ }
39
42
40
43
const WITNESS_FLAG_BYTES : u64 = 2 ;
41
44
42
45
let mut output_value = Amount :: ZERO ;
43
46
for output in tx. output . iter ( ) {
44
47
output_value += output. value ;
45
- if output_value >= input_value { return Err ( ( ) ) ; }
48
+ if output_value >= input_value {
49
+ return Err ( ( ) ) ;
50
+ }
46
51
}
47
52
48
53
let dust_value = change_destination_script. minimal_non_dust ( ) ;
49
- let mut change_output = TxOut {
50
- script_pubkey : change_destination_script,
51
- value : Amount :: ZERO ,
52
- } ;
54
+ let mut change_output = TxOut { script_pubkey : change_destination_script, value : Amount :: ZERO } ;
53
55
let change_len = change_output. consensus_encode ( & mut sink ( ) ) . unwrap ( ) ;
54
56
let starting_weight = tx. weight ( ) . to_wu ( ) + WITNESS_FLAG_BYTES + witness_max_weight as u64 ;
55
57
let starting_fees = ( starting_weight as i64 ) * feerate_sat_per_1000_weight as i64 / 1000 ;
@@ -76,60 +78,58 @@ mod tests {
76
78
use super :: * ;
77
79
78
80
use bitcoin:: amount:: Amount ;
79
- use bitcoin:: locktime:: absolute:: LockTime ;
80
- use bitcoin:: transaction:: { TxIn , OutPoint , Version } ;
81
- use bitcoin:: script:: Builder ;
82
81
use bitcoin:: hash_types:: Txid ;
83
82
use bitcoin:: hashes:: Hash ;
84
83
use bitcoin:: hex:: FromHex ;
84
+ use bitcoin:: locktime:: absolute:: LockTime ;
85
+ use bitcoin:: script:: Builder ;
86
+ use bitcoin:: transaction:: { OutPoint , TxIn , Version } ;
85
87
use bitcoin:: { PubkeyHash , Sequence , Witness } ;
86
88
87
89
use alloc:: vec;
88
90
89
91
#[ test]
90
92
fn sort_output_by_value ( ) {
91
93
let txout1 = TxOut {
92
- value : Amount :: from_sat ( 100 ) ,
93
- script_pubkey : Builder :: new ( ) . push_int ( 0 ) . into_script ( )
94
+ value : Amount :: from_sat ( 100 ) ,
95
+ script_pubkey : Builder :: new ( ) . push_int ( 0 ) . into_script ( ) ,
94
96
} ;
95
97
let txout1_ = txout1. clone ( ) ;
96
98
97
99
let txout2 = TxOut {
98
100
value : Amount :: from_sat ( 99 ) ,
99
- script_pubkey : Builder :: new ( ) . push_int ( 0 ) . into_script ( )
101
+ script_pubkey : Builder :: new ( ) . push_int ( 0 ) . into_script ( ) ,
100
102
} ;
101
103
let txout2_ = txout2. clone ( ) ;
102
104
103
105
let mut outputs = vec ! [ ( txout1, "ignore" ) , ( txout2, "ignore" ) ] ;
104
- sort_outputs ( & mut outputs, |_, _| { unreachable ! ( ) ; } ) ;
106
+ sort_outputs ( & mut outputs, |_, _| {
107
+ unreachable ! ( ) ;
108
+ } ) ;
105
109
106
- assert_eq ! (
107
- & outputs,
108
- & vec![ ( txout2_, "ignore" ) , ( txout1_, "ignore" ) ]
109
- ) ;
110
+ assert_eq ! ( & outputs, & vec![ ( txout2_, "ignore" ) , ( txout1_, "ignore" ) ] ) ;
110
111
}
111
112
112
113
#[ test]
113
114
fn sort_output_by_script_pubkey ( ) {
114
115
let txout1 = TxOut {
115
- value : Amount :: from_sat ( 100 ) ,
116
+ value : Amount :: from_sat ( 100 ) ,
116
117
script_pubkey : Builder :: new ( ) . push_int ( 3 ) . into_script ( ) ,
117
118
} ;
118
119
let txout1_ = txout1. clone ( ) ;
119
120
120
121
let txout2 = TxOut {
121
122
value : Amount :: from_sat ( 100 ) ,
122
- script_pubkey : Builder :: new ( ) . push_int ( 1 ) . push_int ( 2 ) . into_script ( )
123
+ script_pubkey : Builder :: new ( ) . push_int ( 1 ) . push_int ( 2 ) . into_script ( ) ,
123
124
} ;
124
125
let txout2_ = txout2. clone ( ) ;
125
126
126
127
let mut outputs = vec ! [ ( txout1, "ignore" ) , ( txout2, "ignore" ) ] ;
127
- sort_outputs ( & mut outputs, |_, _| { unreachable ! ( ) ; } ) ;
128
+ sort_outputs ( & mut outputs, |_, _| {
129
+ unreachable ! ( ) ;
130
+ } ) ;
128
131
129
- assert_eq ! (
130
- & outputs,
131
- & vec![ ( txout2_, "ignore" ) , ( txout1_, "ignore" ) ]
132
- ) ;
132
+ assert_eq ! ( & outputs, & vec![ ( txout2_, "ignore" ) , ( txout1_, "ignore" ) ] ) ;
133
133
}
134
134
135
135
#[ test]
@@ -148,29 +148,28 @@ mod tests {
148
148
let txout2_ = txout2. clone ( ) ;
149
149
150
150
let mut outputs = vec ! [ ( txout1, "ignore" ) , ( txout2, "ignore" ) ] ;
151
- sort_outputs ( & mut outputs, |_, _| { unreachable ! ( ) ; } ) ;
151
+ sort_outputs ( & mut outputs, |_, _| {
152
+ unreachable ! ( ) ;
153
+ } ) ;
152
154
153
155
assert_eq ! ( & outputs, & vec![ ( txout1_, "ignore" ) , ( txout2_, "ignore" ) ] ) ;
154
156
}
155
157
156
158
#[ test]
157
159
fn sort_output_tie_breaker_test ( ) {
158
160
let txout1 = TxOut {
159
- value : Amount :: from_sat ( 100 ) ,
160
- script_pubkey : Builder :: new ( ) . push_int ( 1 ) . push_int ( 2 ) . into_script ( )
161
+ value : Amount :: from_sat ( 100 ) ,
162
+ script_pubkey : Builder :: new ( ) . push_int ( 1 ) . push_int ( 2 ) . into_script ( ) ,
161
163
} ;
162
164
let txout1_ = txout1. clone ( ) ;
163
165
164
166
let txout2 = txout1. clone ( ) ;
165
167
let txout2_ = txout1. clone ( ) ;
166
168
167
169
let mut outputs = vec ! [ ( txout1, 420 ) , ( txout2, 69 ) ] ;
168
- sort_outputs ( & mut outputs, |a, b| { a. cmp ( b) } ) ;
170
+ sort_outputs ( & mut outputs, |a, b| a. cmp ( b) ) ;
169
171
170
- assert_eq ! (
171
- & outputs,
172
- & vec![ ( txout2_, 69 ) , ( txout1_, 420 ) ]
173
- ) ;
172
+ assert_eq ! ( & outputs, & vec![ ( txout2_, 69 ) , ( txout1_, 420 ) ] ) ;
174
173
}
175
174
176
175
fn script_from_hex ( hex_str : & str ) -> ScriptBuf {
@@ -276,7 +275,7 @@ mod tests {
276
275
assert_eq ! ( tx. output[ 0 ] . value. to_sat( ) , 546 ) ;
277
276
assert_eq ! ( tx. output[ 0 ] . script_pubkey, output_spk) ;
278
277
// New weight is exactly the fee we wanted.
279
- assert_eq ! ( tx. weight( ) . to_wu( ) / 4 , 590 - 546 ) ;
278
+ assert_eq ! ( tx. weight( ) . to_wu( ) / 4 , 590 - 546 ) ;
280
279
281
280
tx. output . pop ( ) ;
282
281
// The only change is the addition of one output.
0 commit comments