mirror of
https://github.com/lightninglabs/loop.git
synced 2026-08-13 12:33:03 +02:00
staticaddr: accept production taproot channels
LND v0.21 exposes CommitmentType_TAPROOT as the production taproot channel commitment type, while SIMPLE_TAPROOT remains a legacy taproot enum. Static address channel opens previously rejected TAPROOT and only classified SIMPLE_TAPROOT as a taproot output for fee and weight estimates. Accept TAPROOT in the static address open-channel validator and keep accepting SIMPLE_TAPROOT for compatibility. Treat both taproot commitment enums as P2TR outputs for deposit-selection and withdrawal fee estimates. Callers using the production enum then get the same weight accounting as the legacy taproot enum. This does not change the CLI mapping for user-facing channel_type=taproot. It only makes the static address path compatible with callers that already send LND production taproot commitment type.
This commit is contained in:
parent
a92f6bc875
commit
09c92527ea
6 changed files with 46 additions and 25 deletions
|
|
@ -773,6 +773,9 @@ func resolveCommitmentType(commitmentType lnrpc.CommitmentType) (
|
|||
case lnrpc.CommitmentType_SIMPLE_TAPROOT:
|
||||
return lnrpc.CommitmentType_SIMPLE_TAPROOT, nil
|
||||
|
||||
case lnrpc.CommitmentType_TAPROOT:
|
||||
return lnrpc.CommitmentType_TAPROOT, nil
|
||||
|
||||
default:
|
||||
return lnrpc.CommitmentType_UNKNOWN_COMMITMENT_TYPE, fmt.Errorf(
|
||||
"unsupported commitment type %v", commitmentType,
|
||||
|
|
|
|||
|
|
@ -573,6 +573,11 @@ func TestResolveCommitmentType(t *testing.T) {
|
|||
commitmentType: lnrpc.CommitmentType_SIMPLE_TAPROOT,
|
||||
expectedType: lnrpc.CommitmentType_SIMPLE_TAPROOT,
|
||||
},
|
||||
{
|
||||
name: "production taproot supported",
|
||||
commitmentType: lnrpc.CommitmentType_TAPROOT,
|
||||
expectedType: lnrpc.CommitmentType_TAPROOT,
|
||||
},
|
||||
{
|
||||
name: "legacy rejected",
|
||||
commitmentType: lnrpc.CommitmentType_LEGACY,
|
||||
|
|
|
|||
|
|
@ -232,8 +232,10 @@ func estimateFee(numInputs int, feeRate chainfee.SatPerKWeight,
|
|||
|
||||
// Add the funding output based on commitment type.
|
||||
switch commitmentType {
|
||||
case lnrpc.CommitmentType_SIMPLE_TAPROOT:
|
||||
case lnrpc.CommitmentType_SIMPLE_TAPROOT,
|
||||
lnrpc.CommitmentType_TAPROOT:
|
||||
we.AddP2TROutput()
|
||||
|
||||
default:
|
||||
we.AddP2WSHOutput()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -271,9 +271,6 @@ func TestSelectDeposits(t *testing.T) {
|
|||
// High fee rate: 100 sat/vbyte = 25000 sat/kw.
|
||||
highFeeRate := chainfee.SatPerKVByte(100_000).FeePerKWeight()
|
||||
|
||||
anchors := lnrpc.CommitmentType_ANCHORS
|
||||
taproot := lnrpc.CommitmentType_SIMPLE_TAPROOT
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
deposits []*deposit.Deposit
|
||||
|
|
@ -290,7 +287,7 @@ func TestSelectDeposits(t *testing.T) {
|
|||
deposits: makeDeposits(1_000, 2_000),
|
||||
amount: 1_000_000,
|
||||
feeRate: lowFeeRate,
|
||||
commitmentType: anchors,
|
||||
commitmentType: lnrpc.CommitmentType_ANCHORS,
|
||||
wantErr: "insufficient funds",
|
||||
},
|
||||
{
|
||||
|
|
@ -298,7 +295,7 @@ func TestSelectDeposits(t *testing.T) {
|
|||
deposits: makeDeposits(100_000),
|
||||
amount: 100_000,
|
||||
feeRate: lowFeeRate,
|
||||
commitmentType: anchors,
|
||||
commitmentType: lnrpc.CommitmentType_ANCHORS,
|
||||
wantErr: "insufficient funds",
|
||||
},
|
||||
{
|
||||
|
|
@ -310,7 +307,7 @@ func TestSelectDeposits(t *testing.T) {
|
|||
deposits: makeDeposits(51_000),
|
||||
amount: 50_000,
|
||||
feeRate: highFeeRate,
|
||||
commitmentType: anchors,
|
||||
commitmentType: lnrpc.CommitmentType_ANCHORS,
|
||||
wantErr: "insufficient funds",
|
||||
},
|
||||
{
|
||||
|
|
@ -327,7 +324,7 @@ func TestSelectDeposits(t *testing.T) {
|
|||
),
|
||||
amount: 400_000,
|
||||
feeRate: highFeeRate,
|
||||
commitmentType: anchors,
|
||||
commitmentType: lnrpc.CommitmentType_ANCHORS,
|
||||
wantCount: 2,
|
||||
validate: func(t *testing.T, selected []*deposit.Deposit) {
|
||||
require.Equal(
|
||||
|
|
@ -345,7 +342,7 @@ func TestSelectDeposits(t *testing.T) {
|
|||
deposits: makeDeposits(500_000),
|
||||
amount: 100_000,
|
||||
feeRate: lowFeeRate,
|
||||
commitmentType: anchors,
|
||||
commitmentType: lnrpc.CommitmentType_ANCHORS,
|
||||
wantCount: 1,
|
||||
},
|
||||
{
|
||||
|
|
@ -353,7 +350,7 @@ func TestSelectDeposits(t *testing.T) {
|
|||
deposits: makeDeposits(60_000, 60_000),
|
||||
amount: 100_000,
|
||||
feeRate: lowFeeRate,
|
||||
commitmentType: anchors,
|
||||
commitmentType: lnrpc.CommitmentType_ANCHORS,
|
||||
wantCount: 2,
|
||||
},
|
||||
{
|
||||
|
|
@ -361,7 +358,7 @@ func TestSelectDeposits(t *testing.T) {
|
|||
deposits: makeDeposits(10_000, 200_000, 50_000),
|
||||
amount: 100_000,
|
||||
feeRate: lowFeeRate,
|
||||
commitmentType: anchors,
|
||||
commitmentType: lnrpc.CommitmentType_ANCHORS,
|
||||
wantCount: 1,
|
||||
validate: func(t *testing.T, selected []*deposit.Deposit) {
|
||||
// Should pick the 200k deposit.
|
||||
|
|
@ -388,13 +385,13 @@ func TestSelectDeposits(t *testing.T) {
|
|||
deposits: makeDeposits(35_500, 35_500, 10_000),
|
||||
amount: 50_000,
|
||||
feeRate: highFeeRate,
|
||||
commitmentType: anchors,
|
||||
commitmentType: lnrpc.CommitmentType_ANCHORS,
|
||||
wantCount: 3,
|
||||
validate: func(t *testing.T, selected []*deposit.Deposit) {
|
||||
total := depositSum(selected)
|
||||
fee := estimateFee(
|
||||
len(selected), highFeeRate,
|
||||
anchors,
|
||||
lnrpc.CommitmentType_ANCHORS,
|
||||
)
|
||||
require.GreaterOrEqual(
|
||||
t, total,
|
||||
|
|
@ -407,7 +404,7 @@ func TestSelectDeposits(t *testing.T) {
|
|||
deposits: makeDeposits(40_000, 40_000, 40_000),
|
||||
amount: 100_000,
|
||||
feeRate: lowFeeRate,
|
||||
commitmentType: anchors,
|
||||
commitmentType: lnrpc.CommitmentType_ANCHORS,
|
||||
wantCount: 3,
|
||||
},
|
||||
{
|
||||
|
|
@ -415,7 +412,7 @@ func TestSelectDeposits(t *testing.T) {
|
|||
deposits: makeDeposits(100_000, 50_000),
|
||||
amount: 99_000,
|
||||
feeRate: 0,
|
||||
commitmentType: anchors,
|
||||
commitmentType: lnrpc.CommitmentType_ANCHORS,
|
||||
wantCount: 1,
|
||||
validate: func(t *testing.T, selected []*deposit.Deposit) {
|
||||
// With zero fee, 100k covers 99k + 0 + dust.
|
||||
|
|
@ -430,12 +427,12 @@ func TestSelectDeposits(t *testing.T) {
|
|||
deposits: makeDeposits(200_000, 100_000, 50_000),
|
||||
amount: 100_000,
|
||||
feeRate: highFeeRate,
|
||||
commitmentType: anchors,
|
||||
commitmentType: lnrpc.CommitmentType_ANCHORS,
|
||||
validate: func(t *testing.T, selected []*deposit.Deposit) {
|
||||
total := depositSum(selected)
|
||||
fee := estimateFee(
|
||||
len(selected), highFeeRate,
|
||||
anchors,
|
||||
lnrpc.CommitmentType_ANCHORS,
|
||||
)
|
||||
require.GreaterOrEqual(
|
||||
t, total,
|
||||
|
|
@ -448,7 +445,15 @@ func TestSelectDeposits(t *testing.T) {
|
|||
deposits: makeDeposits(500_000),
|
||||
amount: 100_000,
|
||||
feeRate: lowFeeRate,
|
||||
commitmentType: taproot,
|
||||
commitmentType: lnrpc.CommitmentType_SIMPLE_TAPROOT,
|
||||
wantCount: 1,
|
||||
},
|
||||
{
|
||||
name: "production taproot commitment type",
|
||||
deposits: makeDeposits(500_000),
|
||||
amount: 100_000,
|
||||
feeRate: lowFeeRate,
|
||||
commitmentType: lnrpc.CommitmentType_TAPROOT,
|
||||
wantCount: 1,
|
||||
},
|
||||
{
|
||||
|
|
@ -459,12 +464,12 @@ func TestSelectDeposits(t *testing.T) {
|
|||
),
|
||||
amount: 50_000,
|
||||
feeRate: lowFeeRate,
|
||||
commitmentType: anchors,
|
||||
commitmentType: lnrpc.CommitmentType_ANCHORS,
|
||||
validate: func(t *testing.T, selected []*deposit.Deposit) {
|
||||
total := depositSum(selected)
|
||||
fee := estimateFee(
|
||||
len(selected), lowFeeRate,
|
||||
anchors,
|
||||
lnrpc.CommitmentType_ANCHORS,
|
||||
)
|
||||
require.GreaterOrEqual(
|
||||
t, total,
|
||||
|
|
@ -484,12 +489,12 @@ func TestSelectDeposits(t *testing.T) {
|
|||
),
|
||||
amount: 150_000,
|
||||
feeRate: lowFeeRate,
|
||||
commitmentType: anchors,
|
||||
commitmentType: lnrpc.CommitmentType_ANCHORS,
|
||||
validate: func(t *testing.T, selected []*deposit.Deposit) {
|
||||
total := depositSum(selected)
|
||||
fee := estimateFee(
|
||||
len(selected), lowFeeRate,
|
||||
anchors,
|
||||
lnrpc.CommitmentType_ANCHORS,
|
||||
)
|
||||
// Core invariant: selected amount covers
|
||||
// requested amount + fee + dust.
|
||||
|
|
@ -506,7 +511,7 @@ func TestSelectDeposits(t *testing.T) {
|
|||
deposits: makeDeposits(10_000, 20_000, 300_000),
|
||||
amount: 100_000,
|
||||
feeRate: lowFeeRate,
|
||||
commitmentType: anchors,
|
||||
commitmentType: lnrpc.CommitmentType_ANCHORS,
|
||||
wantCount: 1,
|
||||
validate: func(t *testing.T, selected []*deposit.Deposit) {
|
||||
require.Equal(
|
||||
|
|
@ -525,7 +530,7 @@ func TestSelectDeposits(t *testing.T) {
|
|||
deposits: makeDeposits(60_000, 60_000),
|
||||
amount: 50_000,
|
||||
feeRate: highFeeRate,
|
||||
commitmentType: anchors,
|
||||
commitmentType: lnrpc.CommitmentType_ANCHORS,
|
||||
wantCount: 2,
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -235,6 +235,11 @@ func TestCalculateWithdrawalTxValuesCommitmentTypeParity(t *testing.T) {
|
|||
commitmentType: lnrpc.CommitmentType_SIMPLE_TAPROOT,
|
||||
addr: taprootAddr,
|
||||
},
|
||||
{
|
||||
name: "production taproot and p2tr",
|
||||
commitmentType: lnrpc.CommitmentType_TAPROOT,
|
||||
addr: taprootAddr,
|
||||
},
|
||||
}
|
||||
|
||||
selectedAmounts := []btcutil.Amount{
|
||||
|
|
|
|||
|
|
@ -1108,7 +1108,8 @@ func WithdrawalTxWeight(numInputs int, sweepAddress btcutil.Address,
|
|||
|
||||
if commitmentType != lnrpc.CommitmentType_UNKNOWN_COMMITMENT_TYPE {
|
||||
switch commitmentType {
|
||||
case lnrpc.CommitmentType_SIMPLE_TAPROOT:
|
||||
case lnrpc.CommitmentType_SIMPLE_TAPROOT,
|
||||
lnrpc.CommitmentType_TAPROOT:
|
||||
weightEstimator.AddP2TROutput()
|
||||
|
||||
default:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue