Skip to content

Commit

Permalink
swap: fix leaf estimation in AddSuccessToEstimator
Browse files Browse the repository at this point in the history
According to AddTapscriptInput's godoc, the first argument (leafWitnessSize)
must include not the whole size of witness, but only the size of data consumed
by the revealed script. Previously the value was too high, because it also
included the following extra elements: number_of_witness_elements (1 byte),
witness script and its size, control block and its size.

Tests for greedy_batch_selection were affected by this change.
  • Loading branch information
starius committed Jul 18, 2024
1 parent bed4b17 commit 3303780
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 6 deletions.
16 changes: 12 additions & 4 deletions swap/htlc.go
Original file line number Diff line number Diff line change
Expand Up @@ -266,8 +266,6 @@ func (h *Htlc) GenSuccessWitness(receiverSig []byte,

// AddSuccessToEstimator adds a successful spend to a weight estimator.
func (h *Htlc) AddSuccessToEstimator(estimator *input.TxWeightEstimator) error {
maxSuccessWitnessSize := h.MaxSuccessWitnessSize()

switch h.OutputType {
case HtlcP2TR:
// Generate tapscript.
Expand All @@ -283,10 +281,20 @@ func (h *Htlc) AddSuccessToEstimator(estimator *input.TxWeightEstimator) error {
trHtlc.InternalPubKey, successLeaf, timeoutLeafHash[:],
)

estimator.AddTapscriptInput(maxSuccessWitnessSize, tapscript)
// The leaf witness size must be calculated without the byte
// that accounts for the number of witness elements, only the
// total size of all elements on the stack that are consumed by
// the revealed script should be counted. Consumed elements:
// - sigLength: 1 byte
// - sig: 64 bytes
// - preimage_length: 1 byte
// - preimage: 32 bytes
const leafWitnessSize = 1 + 64 + 1 + 32

estimator.AddTapscriptInput(leafWitnessSize, tapscript)

case HtlcP2WSH:
estimator.AddWitnessInput(maxSuccessWitnessSize)
estimator.AddWitnessInput(h.MaxSuccessWitnessSize())
}

return nil
Expand Down
66 changes: 64 additions & 2 deletions sweepbatcher/greedy_batch_selection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const (
highFeeRate = chainfee.SatPerKWeight(30000)

coopInputWeight = lntypes.WeightUnit(230)
nonCoopInputWeight = lntypes.WeightUnit(521)
nonCoopInputWeight = lntypes.WeightUnit(393)
nonCoopPenalty = nonCoopInputWeight - coopInputWeight
coopNewBatchWeight = lntypes.WeightUnit(444)
nonCoopNewBatchWeight = coopNewBatchWeight + nonCoopPenalty
Expand All @@ -31,7 +31,7 @@ const (
coopTwoSweepBatchWeight = coopNewBatchWeight + coopInputWeight
nonCoopTwoSweepBatchWeight = coopTwoSweepBatchWeight +
2*nonCoopPenalty
v2v3BatchWeight = nonCoopTwoSweepBatchWeight - 153
v2v3BatchWeight = nonCoopTwoSweepBatchWeight - 25
)

// testHtlcV2SuccessEstimator adds weight of non-cooperative input to estimator
Expand Down Expand Up @@ -523,6 +523,37 @@ func TestSelectBatches(t *testing.T) {
NonCoopWeight: nonCoopNewBatchWeight,
NonCoopHint: true,
},
wantBestBatchesIds: []int32{2, newBatchSignal, 1},
},

{
name: "high fee noncoop sweep, large batches",
batches: []feeDetails{
{
BatchId: 1,
FeeRate: lowFeeRate,
CoopWeight: 10000,
NonCoopWeight: 15000,
},
{
BatchId: 2,
FeeRate: highFeeRate,
CoopWeight: 10000,
NonCoopWeight: 15000,
},
},
sweep: feeDetails{
FeeRate: highFeeRate,
CoopWeight: coopInputWeight,
NonCoopWeight: nonCoopInputWeight,
NonCoopHint: true,
},
oneSweepBatch: feeDetails{
FeeRate: highFeeRate,
CoopWeight: coopNewBatchWeight,
NonCoopWeight: nonCoopNewBatchWeight,
NonCoopHint: true,
},
wantBestBatchesIds: []int32{newBatchSignal, 2, 1},
},

Expand Down Expand Up @@ -586,6 +617,37 @@ func TestSelectBatches(t *testing.T) {
NonCoopWeight: nonCoopNewBatchWeight,
NonCoopHint: true,
},
wantBestBatchesIds: []int32{1, newBatchSignal, 2},
},

{
name: "low fee noncoop sweep, large batches",
batches: []feeDetails{
{
BatchId: 1,
FeeRate: lowFeeRate,
CoopWeight: 10000,
NonCoopWeight: 15000,
},
{
BatchId: 2,
FeeRate: highFeeRate,
CoopWeight: 10000,
NonCoopWeight: 15000,
},
},
sweep: feeDetails{
FeeRate: lowFeeRate,
CoopWeight: coopInputWeight,
NonCoopWeight: nonCoopInputWeight,
NonCoopHint: true,
},
oneSweepBatch: feeDetails{
FeeRate: lowFeeRate,
CoopWeight: coopNewBatchWeight,
NonCoopWeight: nonCoopNewBatchWeight,
NonCoopHint: true,
},
wantBestBatchesIds: []int32{newBatchSignal, 1, 2},
},

Expand Down

0 comments on commit 3303780

Please sign in to comment.