4040import bisq .core .trade .ClosedTradableManager ;
4141import bisq .core .trade .TradeManager ;
4242import bisq .core .trade .bisq_v1 .FailedTradesManager ;
43+ import bisq .core .trade .model .bisq_v1 .Contract ;
4344import bisq .core .trade .model .bisq_v1 .Trade ;
4445import bisq .core .trade .protocol .bisq_v5 .model .StagedPayoutTxParameters ;
4546
5556import bisq .common .util .Hex ;
5657import bisq .common .util .Tuple2 ;
5758
59+ import org .bitcoinj .core .Coin ;
5860import org .bitcoinj .core .NetworkParameters ;
5961import org .bitcoinj .core .Transaction ;
6062import org .bitcoinj .core .TransactionInput ;
@@ -351,21 +353,34 @@ private static boolean firstOutputConnectsToFirstInput(Transaction parent, Trans
351353 }
352354
353355 public void verifyDelayedPayoutTxReceivers (Transaction depositTx , Transaction delayedPayoutTx , Dispute dispute ) {
354- long inputAmount = depositTx .getOutput (0 ).getValue ().value ;
355- int selectionHeight = dispute .getBurningManSelectionHeight ();
356-
357- List <Tuple2 <Long , String >> receivers = delayedPayoutTxReceiverService .getReceivers (
358- selectionHeight ,
359- inputAmount ,
360- dispute .getTradeTxFee (),
361- DelayedPayoutTxReceiverService .ReceiverFlag .flagsActivatedBy (dispute .getTradeDate ()));
362- log .info ("Verify delayedPayoutTx using selectionHeight {} and receivers {}" , selectionHeight , receivers );
363- checkArgument (delayedPayoutTx .getOutputs ().size () == receivers .size (),
364- "Number of outputs must equal number of receivers" );
365- checkOutputsPrefixMatchesReceivers (delayedPayoutTx , receivers );
356+ if (dispute .isUsingLegacyBurningMan ()) {
357+ checkArgument (delayedPayoutTx .getOutputs ().size () == 1 ,
358+ "delayedPayoutTx must have 1 output when using legacy BM" );
359+ NetworkParameters params = btcWalletService .getParams ();
360+ TransactionOutput transactionOutput = delayedPayoutTx .getOutput (0 );
361+ String outputAddress = transactionOutput .getScriptPubKey ().getToAddress (params ).toString ();
362+ checkArgument (outputAddress .equals (dispute .getDonationAddressOfDelayedPayoutTx ()),
363+ "Output address does not match donation address (%s). transactionOutput=%s" ,
364+ dispute .getDonationAddressOfDelayedPayoutTx (), transactionOutput );
365+ } else {
366+ long inputAmount = depositTx .getOutput (0 ).getValue ().value ;
367+ int selectionHeight = dispute .getBurningManSelectionHeight ();
368+
369+ List <Tuple2 <Long , String >> receivers = delayedPayoutTxReceiverService .getReceivers (
370+ selectionHeight ,
371+ inputAmount ,
372+ dispute .getTradeTxFee (),
373+ DelayedPayoutTxReceiverService .ReceiverFlag .flagsActivatedBy (dispute .getTradeDate ()));
374+ log .info ("Verify delayedPayoutTx using selectionHeight {} and receivers {}" , selectionHeight , receivers );
375+ checkArgument (delayedPayoutTx .getOutputs ().size () == receivers .size (),
376+ "Number of outputs must equal number of receivers" );
377+ checkOutputsPrefixMatchesReceivers (delayedPayoutTx , receivers );
378+ }
366379 }
367380
368381 public void verifyRedirectTxReceivers (Transaction warningTx , Transaction redirectTx , Dispute dispute ) {
382+ checkArgument (!dispute .isUsingLegacyBurningMan (), "Legacy BM use not permitted with redirectTx" );
383+
369384 long inputAmount = warningTx .getOutput (0 ).getValue ().value ;
370385 long inputAmountMinusFeeBumpAmount = inputAmount - StagedPayoutTxParameters .REDIRECT_TX_FEE_BUMP_OUTPUT_VALUE ;
371386 int selectionHeight = dispute .getBurningManSelectionHeight ();
@@ -389,11 +404,33 @@ private void checkOutputsPrefixMatchesReceivers(Transaction delayedPayoutOrRedir
389404 TransactionOutput transactionOutput = delayedPayoutOrRedirectTx .getOutput (i );
390405 Tuple2 <Long , String > receiverTuple = receivers .get (i );
391406 checkArgument (transactionOutput .getScriptPubKey ().getToAddress (params ).toString ().equals (receiverTuple .second ),
392- "Output address does not match receiver address (%s). transactionOutput=%s" ,
393- receiverTuple .second , transactionOutput );
407+ "Output address does not match receiver address (%s). transactionOutput=%s, index=%s " ,
408+ receiverTuple .second , transactionOutput , i );
394409 checkArgument (transactionOutput .getValue ().value == receiverTuple .first ,
395- "Output value does not match receiver value (%s). transactionOutput=%s" ,
396- receiverTuple .first , transactionOutput );
410+ "Output value does not match receiver value (%s). transactionOutput=%s, index=%s " ,
411+ receiverTuple .first , transactionOutput , i );
397412 }
398413 }
414+
415+ public void validateCollateralAndPayoutTotals (Transaction depositTx ,
416+ Transaction delayedPayoutOrRedirectTx ,
417+ Dispute dispute ,
418+ DisputeResult disputeResult ) {
419+ Contract contract = dispute .getContract ();
420+ Coin expectedCollateral = contract .getTradeAmount ()
421+ .add (Coin .valueOf (contract .getOfferPayload ().getBuyerSecurityDeposit ()))
422+ .add (Coin .valueOf (contract .getOfferPayload ().getSellerSecurityDeposit ()));
423+ Coin depositOutputValue = depositTx .getOutput (0 ).getValue ();
424+
425+ checkArgument (!depositOutputValue .isLessThan (expectedCollateral ),
426+ "First depositTx output value (%s) is less than expected trade collateral: %s sats" ,
427+ depositOutputValue , expectedCollateral );
428+
429+ Coin totalPayoutAmount = disputeResult .getBuyerPayoutAmount ().add (disputeResult .getSellerPayoutAmount ());
430+ Coin totalReceiverPlusPossibleFeeBumpOutputAmount = delayedPayoutOrRedirectTx .getOutputSum ();
431+
432+ checkArgument (!totalReceiverPlusPossibleFeeBumpOutputAmount .isLessThan (totalPayoutAmount ),
433+ "DPT/redirectTx output sum (%s) is less than proposed refund of %s sats to traders" ,
434+ totalReceiverPlusPossibleFeeBumpOutputAmount , totalPayoutAmount );
435+ }
399436}
0 commit comments