@@ -107,7 +107,7 @@ impl NegotiationContext {
107107 self . outputs
108108 . iter ( )
109109 . 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 )
111111 }
112112
113113 fn received_tx_add_input ( & mut self , msg : & msgs:: TxAddInput ) -> Result < ( ) , AbortReason > {
@@ -147,7 +147,9 @@ impl NegotiationContext {
147147 // - MUST fail the negotiation if:
148148 // - the `scriptPubKey` is not a witness program
149149 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 } ) {
151153 // The receiving node:
152154 // - MUST fail the negotiation if:
153155 // - the `prevtx` and `prevtx_vout` are identical to a previously added
@@ -173,17 +175,14 @@ impl NegotiationContext {
173175 return Err ( AbortReason :: DuplicateSerialId ) ;
174176 }
175177 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 ( )
185183 } ,
186- ) ;
184+ prev_output : prev_out,
185+ } ) ;
187186 self . prevtx_outpoints . insert ( prev_outpoint) ;
188187 Ok ( ( ) )
189188 }
@@ -193,15 +192,14 @@ impl NegotiationContext {
193192 return Err ( AbortReason :: IncorrectSerialIdParity ) ;
194193 }
195194
196- if let Some ( _) = self . inputs . remove ( & msg. serial_id ) {
197- Ok ( ( ) )
198- } else {
195+ self . inputs
196+ . remove ( & msg. serial_id )
199197 // The receiving node:
200198 // - MUST fail the negotiation if:
201199 // - the input or output identified by the `serial_id` was not added by the sender
202200 // - the `serial_id` does not correspond to a currently added input
203- Err ( AbortReason :: SerialIdUnknown )
204- }
201+ . ok_or ( AbortReason :: SerialIdUnknown )
202+ . map ( |_| ( ) )
205203 }
206204
207205 fn received_tx_add_output ( & mut self , msg : & msgs:: TxAddOutput ) -> Result < ( ) , AbortReason > {
@@ -226,7 +224,14 @@ impl NegotiationContext {
226224 // - the sats amount is less than the dust_limit
227225 return Err ( AbortReason :: BelowDustLimit ) ;
228226 }
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 {
230235 // The receiving node:
231236 // - MUST fail the negotiation if:
232237 // - the sats amount is greater than 2,100,000,000,000,000 (TOTAL_BITCOIN_SUPPLY_SATOSHIS)
@@ -257,7 +262,7 @@ impl NegotiationContext {
257262 }
258263
259264 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) ;
261266 Ok ( ( ) )
262267 }
263268
0 commit comments