2
0
mirror of https://github.com/lightninglabs/loop synced 2024-11-08 01:10:29 +00:00

sweepbatcher: fix inaccuracies in fee estimations

Use SigHashDefault instead of SigHashAll in weight estimations.
Actual code uses SigHashDefault, not SigHashAll. SigHashAll is 1wu larger.

Use the actual destination address in weight estimator, not taproot always.
In the test the type of address is P2WPKH, not taproot.

Updated testSweepFetcher to calculate fee, fee rate and weight accurately and
to compare the data observed in the published transaction with the estimates.
This commit is contained in:
Boris Nagaev 2024-06-29 23:55:32 -03:00
parent 44d9147175
commit db5e0d1d27
No known key found for this signature in database
4 changed files with 24 additions and 11 deletions

View File

@ -199,8 +199,7 @@ func estimateBatchWeight(batch *batch) (feeDetails, error) {
// Add inputs.
for _, sweep := range batch.sweeps {
// TODO: it should be txscript.SigHashDefault.
coopWeight.AddTaprootKeySpendInput(txscript.SigHashAll)
coopWeight.AddTaprootKeySpendInput(txscript.SigHashDefault)
err = sweep.htlcSuccessEstimator(&nonCoopWeight)
if err != nil {

View File

@ -17,10 +17,10 @@ const (
lowFeeRate = chainfee.FeePerKwFloor
highFeeRate = chainfee.SatPerKWeight(30000)
coopInputWeight = lntypes.WeightUnit(231)
coopInputWeight = lntypes.WeightUnit(230)
nonCoopInputWeight = lntypes.WeightUnit(521)
nonCoopPenalty = nonCoopInputWeight - coopInputWeight
coopNewBatchWeight = lntypes.WeightUnit(445)
coopNewBatchWeight = lntypes.WeightUnit(444)
nonCoopNewBatchWeight = coopNewBatchWeight + nonCoopPenalty
// p2pkhDiscount is weight discount P2PKH output has over P2TR output.

View File

@ -22,6 +22,7 @@ import (
"github.com/lightninglabs/loop/labels"
"github.com/lightninglabs/loop/loopdb"
"github.com/lightninglabs/loop/swap"
sweeppkg "github.com/lightninglabs/loop/sweep"
"github.com/lightningnetwork/lnd/chainntnfs"
"github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/keychain"
@ -737,7 +738,10 @@ func (b *batch) publishBatch(ctx context.Context) (btcutil.Amount, error) {
return fee, err
}
weightEstimate.AddP2TROutput()
err = sweeppkg.AddOutputEstimate(&weightEstimate, address)
if err != nil {
return fee, err
}
weight := weightEstimate.Weight()
feeForWeight := b.rbfCache.FeeRate.FeeForWeight(weight)
@ -843,8 +847,7 @@ func (b *batch) publishBatchCoop(ctx context.Context) (btcutil.Amount,
PreviousOutPoint: sweep.outpoint,
})
// TODO: it should be txscript.SigHashDefault.
weightEstimate.AddTaprootKeySpendInput(txscript.SigHashAll)
weightEstimate.AddTaprootKeySpendInput(txscript.SigHashDefault)
}
var address btcutil.Address
@ -870,7 +873,10 @@ func (b *batch) publishBatchCoop(ctx context.Context) (btcutil.Amount,
return fee, err, false
}
weightEstimate.AddP2TROutput()
err = sweeppkg.AddOutputEstimate(&weightEstimate, address)
if err != nil {
return fee, err, false
}
weight := weightEstimate.Weight()
feeForWeight := b.rbfCache.FeeRate.FeeForWeight(weight)

View File

@ -9,6 +9,7 @@ import (
"testing"
"time"
"github.com/btcsuite/btcd/blockchain"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/chaincfg/chainhash"
@ -1937,7 +1938,7 @@ func testSweepFetcher(t *testing.T, store testStore,
// Provide min fee rate for the sweep.
feeRate := chainfee.SatPerKWeight(30000)
amt := btcutil.Amount(1_000_000)
weight := lntypes.WeightUnit(445) // Weight for 1-to-1 tx.
weight := lntypes.WeightUnit(396) // Weight for 1-to-1 tx.
expectedFee := feeRate.FeeForWeight(weight)
swap := &loopdb.LoopOutContract{
@ -2000,8 +2001,9 @@ func testSweepFetcher(t *testing.T, store testStore,
}
batcher := NewBatcher(lnd.WalletKit, lnd.ChainNotifier, lnd.Signer,
testMuSig2SignSweep, testVerifySchnorrSig, lnd.ChainParams,
batcherStore, sweepFetcher, WithCustomFeeRate(customFeeRate))
nil, testVerifySchnorrSig, lnd.ChainParams,
batcherStore, sweepFetcher, WithCustomFeeRate(customFeeRate),
WithCustomSignMuSig2(testSignMuSig2func))
var wg sync.WaitGroup
wg.Add(1)
@ -2052,6 +2054,12 @@ func testSweepFetcher(t *testing.T, store testStore,
out := btcutil.Amount(tx.TxOut[0].Value)
gotFee := amt - out
require.Equal(t, expectedFee, gotFee, "fees don't match")
gotWeight := lntypes.WeightUnit(
blockchain.GetTransactionWeight(btcutil.NewTx(tx)),
)
require.Equal(t, weight, gotWeight, "weights don't match")
gotFeeRate := chainfee.NewSatPerKWeight(gotFee, gotWeight)
require.Equal(t, feeRate, gotFeeRate, "fee rates don't match")
// Make sure we have stored the batch.
batches, err := batcherStore.FetchUnconfirmedSweepBatches(ctx)