From 2cc75db6f8e84499294c243c661c7343993eb7fe Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Wed, 10 Aug 2022 18:25:22 -0700 Subject: [PATCH 1/8] server: default sweep addrs to P2TR This change covers sweep addresses for: the breach arbitrator, and watch tower clients. --- server.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server.go b/server.go index 0d2adc7b8..cf8e8a52b 100644 --- a/server.go +++ b/server.go @@ -4534,7 +4534,8 @@ func newSweepPkScriptGen( return func() ([]byte, error) { sweepAddr, err := wallet.NewAddress( - lnwallet.WitnessPubKey, false, lnwallet.DefaultAccountName, + lnwallet.TaprootPubkey, false, + lnwallet.DefaultAccountName, ) if err != nil { return nil, err From cd313eba248f41e573a71b58152f863788a72bed Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Wed, 10 Aug 2022 18:25:35 -0700 Subject: [PATCH 2/8] contractcourt: the breach arb now uses P2TR outputs for sweep addrs --- contractcourt/breacharbiter.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contractcourt/breacharbiter.go b/contractcourt/breacharbiter.go index b5f7583cc..c6fc6c94e 100644 --- a/contractcourt/breacharbiter.go +++ b/contractcourt/breacharbiter.go @@ -1347,9 +1347,9 @@ func (b *BreachArbiter) createSweepTx(inputs []input.Input) (*wire.MsgTx, spendableOutputs = make([]input.Input, 0, len(inputs)) // The justice transaction we construct will be a segwit transaction - // that pays to a p2wkh output. Components such as the version, + // that pays to a p2tr output. Components such as the version, // nLockTime, and output are already included in the TxWeightEstimator. - weightEstimate.AddP2WKHOutput() + weightEstimate.AddP2TROutput() // Next, we iterate over the breached outputs contained in the // retribution info. For each, we switch over the witness type such From dc16f5df53128a8726942100831f9adce43febc3 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Wed, 10 Aug 2022 18:31:07 -0700 Subject: [PATCH 3/8] watchtower: uses P2TR for sweep, delivery, and reward addresses In this commit, we modify the watch tower to use P2TR addrs for just about anything sweep related. One eye sore in this diff are the changes to `backup_task_internal_test.go`. All the values are hard coded, and now either differ by a value of 48, or needed to be modified to account for the new assumptions propagated to rewards values and fees. --- lnd.go | 2 +- watchtower/lookout/justice_descriptor.go | 15 ++++- watchtower/wtclient/backup_task.go | 49 ++++++++++++++++- .../wtclient/backup_task_internal_test.go | 26 ++++++--- watchtower/wtclient/client_test.go | 3 +- watchtower/wtpolicy/policy.go | 55 +++++++++---------- watchtower/wtserver/server_test.go | 3 +- 7 files changed, 107 insertions(+), 46 deletions(-) diff --git a/lnd.go b/lnd.go index eb57995d2..88ec75be9 100644 --- a/lnd.go +++ b/lnd.go @@ -458,7 +458,7 @@ func Main(cfg *Config, lisCfg ListenerCfg, implCfg *ImplementationCfg, Net: cfg.net, NewAddress: func() (btcutil.Address, error) { return activeChainControl.Wallet.NewAddress( - lnwallet.WitnessPubKey, false, + lnwallet.TaprootPubkey, false, lnwallet.DefaultAccountName, ) }, diff --git a/watchtower/lookout/justice_descriptor.go b/watchtower/lookout/justice_descriptor.go index dac18b048..a474d5ccb 100644 --- a/watchtower/lookout/justice_descriptor.go +++ b/watchtower/lookout/justice_descriptor.go @@ -10,6 +10,7 @@ import ( "github.com/btcsuite/btcd/btcutil/txsort" "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" + "github.com/davecgh/go-spew/spew" "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/watchtower/blob" "github.com/lightningnetwork/lnd/watchtower/wtdb" @@ -228,8 +229,8 @@ func (p *JusticeDescriptor) assembleJusticeTxn(txWeight int64, i := inputIndex[inp.outPoint] justiceTxn.TxIn[i].Witness = inp.witness - // Validate the reconstructed witnesses to ensure they are valid - // for the breached inputs. + // Validate the reconstructed witnesses to ensure they are + // valid for the breached inputs. vm, err := txscript.NewEngine( inp.txOut.PkScript, justiceTxn, i, txscript.StandardVerifyFlags, @@ -239,7 +240,9 @@ func (p *JusticeDescriptor) assembleJusticeTxn(txWeight int64, return nil, err } if err := vm.Execute(); err != nil { - return nil, err + log.Debugf("Failed to validate justice transaction: %s", + spew.Sdump(justiceTxn)) + return nil, fmt.Errorf("error validating TX: %v", err) } } @@ -300,6 +303,9 @@ func (p *JusticeDescriptor) CreateJusticeTxn() (*wire.MsgTx, error) { sweepInputs = append(sweepInputs, toLocalInput) + log.Debugf("Found to local witness output=%#v, stack=%v", + toLocalInput.txOut, toLocalInput.witness) + // If the justice kit specifies that we have to sweep the to-remote // output, we'll also try to assemble the output and add it to weight // estimate if successful. @@ -310,6 +316,9 @@ func (p *JusticeDescriptor) CreateJusticeTxn() (*wire.MsgTx, error) { } sweepInputs = append(sweepInputs, toRemoteInput) + log.Debugf("Found to remote witness output=%#v, stack=%v", + toRemoteInput.txOut, toRemoteInput.witness) + if p.JusticeKit.BlobType.IsAnchorChannel() { weightEstimate.AddWitnessInput(input.ToRemoteConfirmedWitnessSize) } else { diff --git a/watchtower/wtclient/backup_task.go b/watchtower/wtclient/backup_task.go index 5ac179c0a..a72689303 100644 --- a/watchtower/wtclient/backup_task.go +++ b/watchtower/wtclient/backup_task.go @@ -7,6 +7,7 @@ import ( "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/btcutil/txsort" + "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" "github.com/lightningnetwork/lnd/channeldb" @@ -151,6 +152,42 @@ func (t *backupTask) inputs() map[wire.OutPoint]input.Input { return inputs } +// addrType returns the type of an address after parsing it and matching it to +// the set of known script templates. +func addrType(pkScript []byte) txscript.ScriptClass { + // We pass in a set of dummy chain params here as they're only needed + // to make the address struct, which we're ignoring anyway (scripts are + // always the same, it's addresses that change across chains). + scriptClass, _, _, _ := txscript.ExtractPkScriptAddrs( + pkScript, &chaincfg.MainNetParams, + ) + + return scriptClass +} + +// addScriptWeight parses the passed pkScript and adds the computed weight cost +// were the script to be added to the justice transaction. +func addScriptWeight(weightEstimate *input.TxWeightEstimator, + pkScript []byte) error { + + switch addrType(pkScript) { //nolint: whitespace + + case txscript.WitnessV0PubKeyHashTy: + weightEstimate.AddP2WKHOutput() + + case txscript.WitnessV0ScriptHashTy: + weightEstimate.AddP2WSHOutput() + + case txscript.WitnessV1TaprootTy: + weightEstimate.AddP2TROutput() + + default: + return fmt.Errorf("invalid addr type: %v", addrType(pkScript)) + } + + return nil +} + // bindSession determines if the backupTask is compatible with the passed // SessionInfo's policy. If no error is returned, the task has been bound to the // session and can be queued to upload to the tower. Otherwise, the bind failed @@ -192,13 +229,19 @@ func (t *backupTask) bindSession(session *wtdb.ClientSessionBody) error { } } - // All justice transactions have a p2wkh output paying to the victim. - weightEstimate.AddP2WKHOutput() + // All justice transactions will either use segwit v0 (p2wkh + p2wsh) + // or segwit v1 (p2tr). + if err := addScriptWeight(&weightEstimate, t.sweepPkScript); err != nil { + return err + } // If the justice transaction has a reward output, add the output's // contribution to the weight estimate. if session.Policy.BlobType.Has(blob.FlagReward) { - weightEstimate.AddP2WKHOutput() + err := addScriptWeight(&weightEstimate, session.RewardPkScript) + if err != nil { + return err + } } if t.chanType.HasAnchors() != session.Policy.IsAnchorChannel() { diff --git a/watchtower/wtclient/backup_task_internal_test.go b/watchtower/wtclient/backup_task_internal_test.go index 9c0a3e20e..7d3178f3e 100644 --- a/watchtower/wtclient/backup_task_internal_test.go +++ b/watchtower/wtclient/backup_task_internal_test.go @@ -247,7 +247,7 @@ func genTaskTest( RewardPkScript: rewardScript, }, bindErr: bindErr, - expSweepScript: makeAddrSlice(22), + expSweepScript: sweepAddr, signer: signer, chanType: chanType, } @@ -259,10 +259,18 @@ var ( blobTypeCommitReward = (blob.FlagCommitOutputs | blob.FlagReward).Type() addr, _ = btcutil.DecodeAddress( - "mrX9vMRYLfVy1BnZbc5gZjuyaqH3ZW2ZHz", &chaincfg.TestNet3Params, + "tb1pw8gzj8clt3v5lxykpgacpju5n8xteskt7gxhmudu6pa70nwfhe6s3unsyk", + &chaincfg.TestNet3Params, ) addrScript, _ = txscript.PayToAddrScript(addr) + + sweepAddrScript, _ = btcutil.DecodeAddress( + "tb1qs3jyc9sf5kak3x0w99cav9u605aeu3t600xxx0", + &chaincfg.TestNet3Params, + ) + + sweepAddr, _ = txscript.PayToAddrScript(sweepAddrScript) ) // TestBackupTaskBind tests the initialization and binding of a backupTask to a @@ -297,9 +305,9 @@ func TestBackupTask(t *testing.T) { expSweepCommitNoRewardBoth int64 = 299241 expSweepCommitNoRewardLocal int64 = 199514 expSweepCommitNoRewardRemote int64 = 99561 - expSweepCommitRewardBoth int64 = 296117 - expSweepCommitRewardLocal int64 = 197390 - expSweepCommitRewardRemote int64 = 98437 + expSweepCommitRewardBoth int64 = 296069 + expSweepCommitRewardLocal int64 = 197342 + expSweepCommitRewardRemote int64 = 98389 sweepFeeRateNoRewardRemoteDust chainfee.SatPerKWeight = 227500 sweepFeeRateRewardRemoteDust chainfee.SatPerKWeight = 175350 ) @@ -307,9 +315,9 @@ func TestBackupTask(t *testing.T) { expSweepCommitNoRewardBoth = 299236 expSweepCommitNoRewardLocal = 199513 expSweepCommitNoRewardRemote = 99557 - expSweepCommitRewardBoth = 296112 - expSweepCommitRewardLocal = 197389 - expSweepCommitRewardRemote = 98433 + expSweepCommitRewardBoth = 296064 + expSweepCommitRewardLocal = 197341 + expSweepCommitRewardRemote = 98385 sweepFeeRateNoRewardRemoteDust = 225400 sweepFeeRateRewardRemoteDust = 174100 } @@ -436,7 +444,7 @@ func TestBackupTask(t *testing.T) { "commit reward, to-remote output only, creates dust", 1, // stateNum 0, // toLocalAmt - 100000, // toRemoteAmt + 108221, // toRemoteAmt blobTypeCommitReward, // blobType sweepFeeRateRewardRemoteDust, // sweepFeeRate addrScript, // rewardScript diff --git a/watchtower/wtclient/client_test.go b/watchtower/wtclient/client_test.go index 83bb27ff7..bba12895c 100644 --- a/watchtower/wtclient/client_test.go +++ b/watchtower/wtclient/client_test.go @@ -58,7 +58,8 @@ var ( // addr is the server's reward address given to watchtower clients. addr, _ = btcutil.DecodeAddress( - "mrX9vMRYLfVy1BnZbc5gZjuyaqH3ZW2ZHz", &chaincfg.TestNet3Params, + "tb1pw8gzj8clt3v5lxykpgacpju5n8xteskt7gxhmudu6pa70nwfhe6s3unsyk", + &chaincfg.TestNet3Params, ) addrScript, _ = txscript.PayToAddrScript(addr) diff --git a/watchtower/wtpolicy/policy.go b/watchtower/wtpolicy/policy.go index 6eb88657b..429f1ffb6 100644 --- a/watchtower/wtpolicy/policy.go +++ b/watchtower/wtpolicy/policy.go @@ -6,7 +6,6 @@ import ( "github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/wire" - "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwallet/chainfee" "github.com/lightningnetwork/lnd/watchtower/blob" @@ -156,7 +155,7 @@ func (p Policy) Validate() error { // of the justice transaction and subtracting an amount that satisfies the // policy's fee rate. func (p *Policy) ComputeAltruistOutput(totalAmt btcutil.Amount, - txWeight int64) (btcutil.Amount, error) { + txWeight int64, sweepScript []byte) (btcutil.Amount, error) { txFee := p.SweepFeeRate.FeeForWeight(txWeight) if txFee > totalAmt { @@ -165,10 +164,9 @@ func (p *Policy) ComputeAltruistOutput(totalAmt btcutil.Amount, sweepAmt := totalAmt - txFee - // TODO(conner): replace w/ configurable dust limit - // Check that the created outputs won't be dusty. The sweep pkscript is - // currently a p2wpkh, so we'll use that script's dust limit. - if sweepAmt < lnwallet.DustLimitForSize(input.P2WPKHSize) { + // Check that the created outputs won't be dusty. We'll base the dust + // computation on the type of the script itself. + if sweepAmt < lnwallet.DustLimitForSize(len(sweepScript)) { return 0, ErrCreatesDust } @@ -180,7 +178,8 @@ func (p *Policy) ComputeAltruistOutput(totalAmt btcutil.Amount, // and reward rate. The reward to he tower is subtracted first, before // splitting the remaining balance amongst the victim and fees. func (p *Policy) ComputeRewardOutputs(totalAmt btcutil.Amount, - txWeight int64) (btcutil.Amount, btcutil.Amount, error) { + txWeight int64, + rewardScript []byte) (btcutil.Amount, btcutil.Amount, error) { txFee := p.SweepFeeRate.FeeForWeight(txWeight) if txFee > totalAmt { @@ -198,10 +197,9 @@ func (p *Policy) ComputeRewardOutputs(totalAmt btcutil.Amount, // input value. sweepAmt := totalAmt - rewardAmt - txFee - // TODO(conner): replace w/ configurable dust limit - // Check that the created outputs won't be dusty. The sweep pkscript is - // currently a p2wpkh, so we'll use that script's dust limit. - if sweepAmt < lnwallet.DustLimitForSize(input.P2WPKHSize) { + // Check that the created outputs won't be dusty. We'll base the dust + // computation on the type of the script itself. + if sweepAmt < lnwallet.DustLimitForSize(len(rewardScript)) { return 0, 0, ErrCreatesDust } @@ -231,15 +229,16 @@ func ComputeRewardAmount(total btcutil.Amount, base, rate uint32) btcutil.Amount return rewardBase + proportional } -// ComputeJusticeTxOuts constructs the justice transaction outputs for the given -// policy. If the policy specifies a reward for the tower, there will be two -// outputs paying to the victim and the tower. Otherwise there will be a single -// output sweeping funds back to the victim. The totalAmt should be the sum of -// any inputs used in the transaction. The passed txWeight should include the -// weight of the outputs for the justice transaction, which is dependent on -// whether the justice transaction has a reward. The sweepPkScript should be the -// pkScript of the victim to which funds will be recovered. The rewardPkScript -// is the pkScript of the tower where its reward will be deposited, and will be +// ComputeJusticeTxOuts constructs the justice transaction outputs for the +// given policy. If the policy specifies a reward for the tower, there will be +// two outputs paying to the victim and the tower. Otherwise there will be a +// single output sweeping funds back to the victim. The totalAmt should be the +// sum of any inputs used in the transaction. The passed txWeight should +// include the weight of the outputs for the justice transaction, which is +// dependent on whether the justice transaction has a reward. The sweepPkScript +// should be the pkScript of the victim to which funds will be recovered. The +// rewardPkScript is the pkScript of the tower where its reward will be +// deposited, and will be // ignored if the blob type does not specify a reward. func (p *Policy) ComputeJusticeTxOuts(totalAmt btcutil.Amount, txWeight int64, sweepPkScript, rewardPkScript []byte) ([]*wire.TxOut, error) { @@ -247,19 +246,19 @@ func (p *Policy) ComputeJusticeTxOuts(totalAmt btcutil.Amount, txWeight int64, var outputs []*wire.TxOut // If the policy specifies a reward for the tower, compute a split of - // the funds based on the policy's parameters. Otherwise, we will use an - // the altruist output computation and sweep as much of the funds back - // to the victim as possible. + // the funds based on the policy's parameters. Otherwise, we will use + // the altruist output computation and sweep as much of the funds + // back to the victim as possible. if p.BlobType.Has(blob.FlagReward) { // Using the total input amount and the transaction's weight, - // compute the sweep and reward amounts. This corresponds to the - // amount returned to the victim and the amount paid to the + // compute the sweep and reward amounts. This corresponds to + // the amount returned to the victim and the amount paid to the // tower, respectively. To do so, the required transaction fee // is subtracted from the total, and the remaining amount is - // divided according to the prenegotiated reward rate from the + // divided according to the pre negotiated reward rate from the // client's session info. sweepAmt, rewardAmt, err := p.ComputeRewardOutputs( - totalAmt, txWeight, + totalAmt, txWeight, rewardPkScript, ) if err != nil { return nil, err @@ -280,7 +279,7 @@ func (p *Policy) ComputeJusticeTxOuts(totalAmt btcutil.Amount, txWeight int64, // returned to the victim. To do so, the required transaction // fee is subtracted from the total input amount. sweepAmt, err := p.ComputeAltruistOutput( - totalAmt, txWeight, + totalAmt, txWeight, sweepPkScript, ) if err != nil { return nil, err diff --git a/watchtower/wtserver/server_test.go b/watchtower/wtserver/server_test.go index be94e9bee..9260e4640 100644 --- a/watchtower/wtserver/server_test.go +++ b/watchtower/wtserver/server_test.go @@ -22,7 +22,8 @@ import ( var ( // addr is the server's reward address given to watchtower clients. addr, _ = btcutil.DecodeAddress( - "mrX9vMRYLfVy1BnZbc5gZjuyaqH3ZW2ZHz", &chaincfg.TestNet3Params, + "tb1pw8gzj8clt3v5lxykpgacpju5n8xteskt7gxhmudu6pa70nwfhe6s3unsyk", + &chaincfg.TestNet3Params, ) addrScript, _ = txscript.PayToAddrScript(addr) From b711120dca661f6e30769a3d15c070a3235f8acf Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Wed, 10 Aug 2022 18:31:37 -0700 Subject: [PATCH 4/8] sweep: change outputs are now P2TR --- sweep/tx_input_set.go | 2 +- sweep/txgenerator.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sweep/tx_input_set.go b/sweep/tx_input_set.go index 9dc48901c..576471032 100644 --- a/sweep/tx_input_set.go +++ b/sweep/tx_input_set.go @@ -139,7 +139,7 @@ func newTxInputSet(wallet Wallet, feePerKW chainfee.SatPerKWeight, func (t *txInputSet) enoughInput() bool { // If we have a change output above dust, then we certainly have enough // inputs to the transaction. - if t.changeOutput >= lnwallet.DustLimitForSize(input.P2WPKHSize) { + if t.changeOutput >= lnwallet.DustLimitForSize(input.P2TRSize) { return true } diff --git a/sweep/txgenerator.go b/sweep/txgenerator.go index 3b07f2d64..20e80a00c 100644 --- a/sweep/txgenerator.go +++ b/sweep/txgenerator.go @@ -111,8 +111,8 @@ func generateInputPartitionings(sweepableInputs []txInput, // continuing with the remaining inputs will only lead to sets // with an even lower output value. if !txInputs.enoughInput() { - // The change output is always a p2wpkh here. - dl := lnwallet.DustLimitForSize(input.P2WPKHSize) + // The change output is always a p2tr here. + dl := lnwallet.DustLimitForSize(input.P2TRSize) log.Debugf("Set value %v (r=%v, c=%v) below dust "+ "limit of %v", txInputs.totalOutput(), txInputs.requiredOutput, txInputs.changeOutput, From bcff2f07de810c0ba07ae48f31a03f07140409f7 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Wed, 10 Aug 2022 18:32:12 -0700 Subject: [PATCH 5/8] rpc: use P2TR addresses when sending funds back to wallet (anchor reserve) --- rpcserver.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpcserver.go b/rpcserver.go index 01c9c9e15..a0358cb17 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -1330,7 +1330,7 @@ func (r *rpcServer) SendCoins(ctx context.Context, // ensures this is an address the wallet knows about, // allowing us to pass the reserved value check. changeAddr, err := r.server.cc.Wallet.NewAddress( - lnwallet.WitnessPubKey, true, + lnwallet.TaprootPubkey, true, lnwallet.DefaultAccountName, ) if err != nil { From 322937a67eb164c8d9eb2e4880655093086d5533 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Wed, 10 Aug 2022 18:33:19 -0700 Subject: [PATCH 6/8] lnwallet: use P2TR addresses for change outputs for funding coin select --- lnwallet/test/test_interface.go | 12 ++++++++---- lnwallet/wallet.go | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/lnwallet/test/test_interface.go b/lnwallet/test/test_interface.go index dd741fd4c..ebaf91e8d 100644 --- a/lnwallet/test/test_interface.go +++ b/lnwallet/test/test_interface.go @@ -2708,6 +2708,14 @@ var walletTests = []walletTestCase{ name: "change output spend confirmation", test: testChangeOutputSpendConfirmation, }, + { + // TODO(guggero): this test should remain second until dual + // funding can properly exchange full UTXO information and we + // can use P2TR change outputs as the funding inputs for a dual + // funded channel. + name: "dual funder workflow", + test: testDualFundingReservationWorkflow, + }, { name: "spend unconfirmed outputs", test: testSpendUnconfirmed, @@ -2744,10 +2752,6 @@ var walletTests = []walletTestCase{ name: "single funding workflow external funding tx", test: testSingleFunderExternalFundingTx, }, - { - name: "dual funder workflow", - test: testDualFundingReservationWorkflow, - }, { name: "output locking", test: testFundingTransactionLockedOutputs, diff --git a/lnwallet/wallet.go b/lnwallet/wallet.go index 8ee8cabc6..49c6410be 100644 --- a/lnwallet/wallet.go +++ b/lnwallet/wallet.go @@ -775,7 +775,7 @@ func (l *LightningWallet) handleFundingReserveRequest(req *InitFundingReserveMsg FeeRate: req.FundingFeePerKw, ChangeAddr: func() (btcutil.Address, error) { return l.NewAddress( - WitnessPubKey, true, DefaultAccountName, + TaprootPubkey, true, DefaultAccountName, ) }, } From 42549519ca6676f27530139ef24f5ad70d254675 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Wed, 10 Aug 2022 18:33:52 -0700 Subject: [PATCH 7/8] lnwallet/chanfunding: assumes all change outputs are P2TR --- lnwallet/chanfunding/coin_select.go | 7 ++++--- lnwallet/chanfunding/coin_select_test.go | 6 +++--- lnwallet/chanfunding/wallet_assembler.go | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/lnwallet/chanfunding/coin_select.go b/lnwallet/chanfunding/coin_select.go index 761f7c032..049d94cdd 100644 --- a/lnwallet/chanfunding/coin_select.go +++ b/lnwallet/chanfunding/coin_select.go @@ -98,8 +98,8 @@ func calculateFees(utxos []Coin, feeRate chainfee.SatPerKWeight) (btcutil.Amount requiredFeeNoChange := feeRate.FeeForWeight(totalWeight) // Estimate the fee required for a transaction with a change output. - // Assume that change output is a P2WKH output. - weightEstimate.AddP2WKHOutput() + // Assume that change output is a P2TR output. + weightEstimate.AddP2TROutput() // Now that we have added the change output, redo the fee // estimate. @@ -209,7 +209,8 @@ func CoinSelectSubtractFees(feeRate chainfee.SatPerKWeight, amt, // Obtain fee estimates both with and without using a change // output. requiredFeeNoChange, requiredFeeWithChange, err := calculateFees( - selectedUtxos, feeRate) + selectedUtxos, feeRate, + ) if err != nil { return nil, 0, 0, err } diff --git a/lnwallet/chanfunding/coin_select_test.go b/lnwallet/chanfunding/coin_select_test.go index 0f3d4ef4b..d243cd358 100644 --- a/lnwallet/chanfunding/coin_select_test.go +++ b/lnwallet/chanfunding/coin_select_test.go @@ -44,7 +44,7 @@ func fundingFee(feeRate chainfee.SatPerKWeight, numInput int, // nolint:unparam // Optionally count a change output. if change { - weightEstimate.AddP2WKHOutput() + weightEstimate.AddP2TROutput() } totalWeight := int64(weightEstimate.Weight()) @@ -81,7 +81,7 @@ func TestCalculateFees(t *testing.T) { }, expectedFeeNoChange: 487, - expectedFeeWithChange: 611, + expectedFeeWithChange: 659, expectedErr: nil, }, @@ -97,7 +97,7 @@ func TestCalculateFees(t *testing.T) { }, expectedFeeNoChange: 579, - expectedFeeWithChange: 703, + expectedFeeWithChange: 751, expectedErr: nil, }, diff --git a/lnwallet/chanfunding/wallet_assembler.go b/lnwallet/chanfunding/wallet_assembler.go index 376360901..6d9c1974e 100644 --- a/lnwallet/chanfunding/wallet_assembler.go +++ b/lnwallet/chanfunding/wallet_assembler.go @@ -21,7 +21,7 @@ import ( // // Steps to final channel provisioning: // 1. Call BindKeys to notify the intent which keys to use when constructing -// the multi-sig output. +// the multi-sig output. // 2. Call CompileFundingTx afterwards to obtain the funding transaction. // // If either of these steps fail, then the Cancel method MUST be called. From 91bc4b540c922192e45b3bb6eea972c7d3d075e3 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Wed, 10 Aug 2022 18:34:03 -0700 Subject: [PATCH 8/8] docs/release-notes: add release notes entry --- docs/release-notes/release-notes-0.15.1.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/release-notes-0.15.1.md b/docs/release-notes/release-notes-0.15.1.md index 15dfef0f4..66da8a210 100644 --- a/docs/release-notes/release-notes-0.15.1.md +++ b/docs/release-notes/release-notes-0.15.1.md @@ -21,12 +21,15 @@ ## Taproot -[`lnd` will now refuse to start if it detects the full node backned does not +[`lnd` will now refuse to start if it detects the full node backend does not support Tapoot](https://github.com/lightningnetwork/lnd/pull/6798). [`lnd` will now use taproot addresses for co-op closes if the remote peer supports the feature.](https://github.com/lightningnetwork/lnd/pull/6633) +The [wallet also creates P2TR change addresses by +default](https://github.com/lightningnetwork/lnd/pull/6810) in most cases. + ## `lncli` * [Add `payment_addr` flag to