@@ -125,6 +125,9 @@ type sweep struct {
125125
126126 // presigned is set, if the sweep should be handled in presigned mode.
127127 presigned bool
128+
129+ // change is the optional change output of the sweep.
130+ change * wire.TxOut
128131}
129132
130133// batchState is the state of the batch.
@@ -1238,6 +1241,7 @@ func (b *batch) createPsbt(unsignedTx *wire.MsgTx, sweeps []sweep) ([]byte,
12381241// constructUnsignedTx creates unsigned tx from the sweeps, paying to the addr.
12391242// It also returns absolute fee (from weight and clamped).
12401243func constructUnsignedTx (sweeps []sweep , address btcutil.Address ,
1244+ changeOutputs map [* wire.TxOut ]btcutil.Address ,
12411245 currentHeight int32 , feeRate chainfee.SatPerKWeight ) (* wire.MsgTx ,
12421246 lntypes.WeightUnit , btcutil.Amount , btcutil.Amount , error ) {
12431247
@@ -1297,6 +1301,20 @@ func constructUnsignedTx(sweeps []sweep, address btcutil.Address,
12971301 "failed: %w" , err )
12981302 }
12991303
1304+ // Add the optional change outputs to weight estimates.
1305+ if changeOutputs != nil && len (changeOutputs ) > 0 {
1306+ for _ , addr := range changeOutputs {
1307+ // Add the output to weight estimates.
1308+ err = sweeppkg .AddOutputEstimate (
1309+ & weightEstimate , addr ,
1310+ )
1311+ if err != nil {
1312+ return nil , 0 , 0 , 0 , fmt .Errorf ("sweep." +
1313+ "AddOutputEstimate failed: %w" , err )
1314+ }
1315+ }
1316+ }
1317+
13001318 // Keep track of the total amount this batch is sweeping back.
13011319 batchAmt := btcutil .Amount (0 )
13021320 for _ , sweep := range sweeps {
@@ -1318,11 +1336,29 @@ func constructUnsignedTx(sweeps []sweep, address btcutil.Address,
13181336 fee := clampBatchFee (feeForWeight , batchAmt )
13191337
13201338 // Add the batch transaction output, which excludes the fees paid to
1321- // miners.
1322- batchTx .AddTxOut (& wire.TxOut {
1323- PkScript : batchPkScript ,
1324- Value : int64 (batchAmt - fee ),
1325- })
1339+ // miners. Reduce the amount by the sum of change outputs, if any.
1340+ if changeOutputs == nil || len (changeOutputs ) == 0 {
1341+ batchTx .AddTxOut (& wire.TxOut {
1342+ PkScript : batchPkScript ,
1343+ Value : int64 (batchAmt - fee ),
1344+ })
1345+ } else if len (changeOutputs ) > 0 {
1346+ // Reduce the batch output by the sum of change outputs.
1347+ var sumChange int64
1348+ for change , _ := range changeOutputs {
1349+ sumChange += change .Value
1350+ }
1351+ batchTx .AddTxOut (& wire.TxOut {
1352+ PkScript : batchPkScript ,
1353+ Value : int64 (batchAmt - fee ) - sumChange ,
1354+ })
1355+ for txOut , _ := range changeOutputs {
1356+ batchTx .AddTxOut (& wire.TxOut {
1357+ PkScript : txOut .PkScript ,
1358+ Value : txOut .Value ,
1359+ })
1360+ }
1361+ }
13261362
13271363 return batchTx , weight , feeForWeight , fee , nil
13281364}
@@ -1396,9 +1432,13 @@ func (b *batch) publishMixedBatch(ctx context.Context) (btcutil.Amount, error,
13961432 attempt )
13971433
13981434 // Construct unsigned batch transaction.
1399- var err error
1435+ var (
1436+ err error
1437+ changeOutputs map [* wire.TxOut ]btcutil.Address
1438+ )
14001439 tx , weight , feeForWeight , fee , err = constructUnsignedTx (
1401- sweeps , address , b .currentHeight , b .rbfCache .FeeRate ,
1440+ sweeps , address , changeOutputs , b .currentHeight ,
1441+ b .rbfCache .FeeRate ,
14021442 )
14031443 if err != nil {
14041444 return 0 , fmt .Errorf ("failed to construct tx: %w" , err ),
0 commit comments