@@ -107,7 +107,7 @@ impl NegotiationContext {
107
107
self . outputs
108
108
. iter ( )
109
109
. filter ( move |( serial_id, _) | self . is_serial_id_valid_for_counterparty ( serial_id) )
110
- . map ( |( _, input_with_prevout ) | input_with_prevout )
110
+ . map ( |( _, output ) | output )
111
111
}
112
112
113
113
fn received_tx_add_input ( & mut self , msg : & msgs:: TxAddInput ) -> Result < ( ) , AbortReason > {
@@ -147,7 +147,9 @@ impl NegotiationContext {
147
147
// - MUST fail the negotiation if:
148
148
// - the `scriptPubKey` is not a witness program
149
149
return Err ( AbortReason :: PrevTxOutInvalid ) ;
150
- } else if !self . prevtx_outpoints . insert ( OutPoint { txid, vout : msg. prevtx_out } ) {
150
+ }
151
+
152
+ if !self . prevtx_outpoints . insert ( OutPoint { txid, vout : msg. prevtx_out } ) {
151
153
// The receiving node:
152
154
// - MUST fail the negotiation if:
153
155
// - the `prevtx` and `prevtx_vout` are identical to a previously added
@@ -173,17 +175,14 @@ impl NegotiationContext {
173
175
return Err ( AbortReason :: DuplicateSerialId ) ;
174
176
}
175
177
let prev_outpoint = OutPoint { txid, vout : msg. prevtx_out } ;
176
- self . inputs . insert (
177
- msg. serial_id ,
178
- TxInputWithPrevOutput {
179
- input : TxIn {
180
- previous_output : prev_outpoint. clone ( ) ,
181
- sequence : Sequence ( msg. sequence ) ,
182
- ..Default :: default ( )
183
- } ,
184
- prev_output : prev_out,
178
+ self . inputs . entry ( msg. serial_id ) . or_insert_with ( || TxInputWithPrevOutput {
179
+ input : TxIn {
180
+ previous_output : prev_outpoint. clone ( ) ,
181
+ sequence : Sequence ( msg. sequence ) ,
182
+ ..Default :: default ( )
185
183
} ,
186
- ) ;
184
+ prev_output : prev_out,
185
+ } ) ;
187
186
self . prevtx_outpoints . insert ( prev_outpoint) ;
188
187
Ok ( ( ) )
189
188
}
@@ -193,15 +192,14 @@ impl NegotiationContext {
193
192
return Err ( AbortReason :: IncorrectSerialIdParity ) ;
194
193
}
195
194
196
- if let Some ( _) = self . inputs . remove ( & msg. serial_id ) {
197
- Ok ( ( ) )
198
- } else {
195
+ self . inputs
196
+ . remove ( & msg. serial_id )
199
197
// The receiving node:
200
198
// - MUST fail the negotiation if:
201
199
// - the input or output identified by the `serial_id` was not added by the sender
202
200
// - the `serial_id` does not correspond to a currently added input
203
- Err ( AbortReason :: SerialIdUnknown )
204
- }
201
+ . ok_or ( AbortReason :: SerialIdUnknown )
202
+ . map ( |_| ( ) )
205
203
}
206
204
207
205
fn received_tx_add_output ( & mut self , msg : & msgs:: TxAddOutput ) -> Result < ( ) , AbortReason > {
@@ -226,7 +224,14 @@ impl NegotiationContext {
226
224
// - the sats amount is less than the dust_limit
227
225
return Err ( AbortReason :: BelowDustLimit ) ;
228
226
}
229
- if msg. sats > TOTAL_BITCOIN_SUPPLY_SATOSHIS {
227
+
228
+ // Check that adding this output would not cause the total output value to exceed the total
229
+ // bitcoin supply.
230
+ let mut outputs_value: u64 = 0 ;
231
+ for output in self . outputs . iter ( ) {
232
+ outputs_value = outputs_value. saturating_add ( output. 1 . value ) ;
233
+ }
234
+ if outputs_value. saturating_add ( msg. sats ) > TOTAL_BITCOIN_SUPPLY_SATOSHIS {
230
235
// The receiving node:
231
236
// - MUST fail the negotiation if:
232
237
// - the sats amount is greater than 2,100,000,000,000,000 (TOTAL_BITCOIN_SUPPLY_SATOSHIS)
@@ -257,7 +262,7 @@ impl NegotiationContext {
257
262
}
258
263
259
264
let output = TxOut { value : msg. sats , script_pubkey : msg. script . clone ( ) } ;
260
- self . outputs . insert ( msg. serial_id , output) ;
265
+ self . outputs . entry ( msg. serial_id ) . or_insert ( output) ;
261
266
Ok ( ( ) )
262
267
}
263
268
0 commit comments