Skip to content

Commit fd4ee81

Browse files
committed
sweepbatcher: consolidate identical change pkscripts
batch separate change outputs with identical pkscripts are tallied up and consolidated to a single change output.
1 parent 6ace0b1 commit fd4ee81

File tree

3 files changed

+80
-7
lines changed

3 files changed

+80
-7
lines changed

sweepbatcher/greedy_batch_selection.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -210,11 +210,21 @@ func estimateBatchWeight(batch *batch) (feeDetails, error) {
210210
err)
211211
}
212212

213-
// Add change output weights.
213+
// Add change output weights. Change outputs with identical pkscript
214+
// will be consolidated into a single output.
215+
changeOutputs := make(map[string]struct{})
214216
for _, s := range batch.sweeps {
215-
if s.change != nil {
216-
weight.AddOutput(s.change.PkScript)
217+
if s.change == nil {
218+
continue
217219
}
220+
221+
pkScriptString := string(s.change.PkScript)
222+
if _, has := changeOutputs[pkScriptString]; has {
223+
continue
224+
}
225+
226+
weight.AddOutput(s.change.PkScript)
227+
changeOutputs[pkScriptString] = struct{}{}
218228
}
219229

220230
// Add inputs.

sweepbatcher/sweep_batch.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,10 +1260,22 @@ func constructUnsignedTx(sweeps []sweep, address btcutil.Address,
12601260
LockTime: uint32(currentHeight),
12611261
}
12621262

1263-
var changeOutputs []*wire.TxOut
1264-
for _, sweep := range sweeps {
1265-
if sweep.change != nil {
1266-
changeOutputs = append(changeOutputs, sweep.change)
1263+
// Consolidate change outputs with identical pkscript.
1264+
changeOutputs := make(map[string]*wire.TxOut)
1265+
for _, s := range sweeps {
1266+
if s.change == nil {
1267+
continue
1268+
}
1269+
1270+
stringPkScript := string(s.change.PkScript)
1271+
if _, has := changeOutputs[stringPkScript]; has {
1272+
changeOutputs[stringPkScript].Value += s.change.Value
1273+
continue
1274+
}
1275+
1276+
changeOutputs[stringPkScript] = &wire.TxOut{
1277+
Value: s.change.Value,
1278+
PkScript: s.change.PkScript,
12671279
}
12681280
}
12691281

sweepbatcher/sweep_batch_test.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,57 @@ func TestConstructUnsignedTx(t *testing.T) {
395395
wantFee: 1248,
396396
},
397397

398+
{
399+
name: "all sweeps identical change pkscripts",
400+
sweeps: []sweep{
401+
{
402+
outpoint: op1,
403+
value: 1_000_000,
404+
},
405+
{
406+
outpoint: op2,
407+
value: 2_000_000,
408+
change: change1,
409+
},
410+
{
411+
outpoint: op3,
412+
value: 3_000_000,
413+
change: change1,
414+
},
415+
},
416+
address: p2trAddress,
417+
currentHeight: 800_000,
418+
feeRate: 1000,
419+
wantTx: &wire.MsgTx{
420+
Version: 2,
421+
LockTime: 800_000,
422+
TxIn: []*wire.TxIn{
423+
{
424+
PreviousOutPoint: op1,
425+
},
426+
{
427+
PreviousOutPoint: op2,
428+
},
429+
{
430+
PreviousOutPoint: op3,
431+
},
432+
},
433+
TxOut: []*wire.TxOut{
434+
{
435+
Value: 5_798_924,
436+
PkScript: p2trPkScript,
437+
},
438+
{
439+
Value: 2 * change1.Value,
440+
PkScript: change1.PkScript,
441+
},
442+
},
443+
},
444+
wantWeight: 1076,
445+
wantFeeForWeight: 1076,
446+
wantFee: 1076,
447+
},
448+
398449
{
399450
name: "change exceeds input value",
400451
sweeps: []sweep{

0 commit comments

Comments
 (0)