ldk_test.go raw
1 package ldk
2
3 import (
4 "testing"
5
6 "github.com/getAlby/ldk-node-go/ldk_node"
7 "github.com/stretchr/testify/assert"
8 "github.com/stretchr/testify/require"
9
10 "github.com/getAlby/hub/tests"
11 )
12
13 func TestGetVssNodeIdentifier(t *testing.T) {
14 mnemonic := "thought turkey ask pottery head say catalog desk pledge elbow naive mimic"
15 expectedVssNodeIdentifier := "751636"
16
17 svc, err := tests.CreateTestServiceWithMnemonic(t, mnemonic, "123")
18 require.NoError(t, err)
19 defer svc.Remove()
20
21 vssNodeIdentifier, err := GetVssNodeIdentifier(svc.Keys)
22 require.NoError(t, err)
23
24 assert.Equal(t, expectedVssNodeIdentifier, vssNodeIdentifier)
25 }
26 func TestGetVssNodeIdentifier2(t *testing.T) {
27 mnemonic := "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
28 expectedVssNodeIdentifier := "770256"
29
30 svc, err := tests.CreateTestServiceWithMnemonic(t, mnemonic, "123")
31 require.NoError(t, err)
32 defer svc.Remove()
33
34 vssNodeIdentifier, err := GetVssNodeIdentifier(svc.Keys)
35 require.NoError(t, err)
36
37 assert.Equal(t, expectedVssNodeIdentifier, vssNodeIdentifier)
38 }
39
40 func makeLsps2OpeningFeeParams(minFeeMsat uint64, proportional uint32, minPaymentSizeMsat uint64, maxPaymentSizeMsat uint64) ldk_node.Lsps2OpeningFeeParams {
41 return ldk_node.Lsps2OpeningFeeParams{
42 MinFeeMsat: minFeeMsat,
43 Proportional: proportional,
44 ValidUntil: "2035-01-01T00:00:00Z",
45 MinLifetime: 4032,
46 MaxClientToSelfDelay: 2016,
47 MinPaymentSizeMsat: minPaymentSizeMsat,
48 MaxPaymentSizeMsat: maxPaymentSizeMsat,
49 Promise: "promise",
50 }
51 }
52
53 func TestComputeLsps2MaxTotalOpeningFeeMsat(t *testing.T) {
54 t.Run("proportional fee above minimum fee", func(t *testing.T) {
55 menu := []ldk_node.Lsps2OpeningFeeParams{
56 // 0.5% of 10M msat = 50k msat > 10k msat minimum
57 makeLsps2OpeningFeeParams(10_000, 5_000, 1_000_000, 100_000_000),
58 }
59 assert.Equal(t, uint64(50_000), computeLsps2MaxTotalOpeningFeeMsat(10_000_000, menu))
60 })
61
62 t.Run("minimum fee above proportional fee", func(t *testing.T) {
63 menu := []ldk_node.Lsps2OpeningFeeParams{
64 // 0.5% of 1M msat = 5k msat < 10k msat minimum
65 makeLsps2OpeningFeeParams(10_000, 5_000, 1_000_000, 100_000_000),
66 }
67 assert.Equal(t, uint64(10_000), computeLsps2MaxTotalOpeningFeeMsat(1_000_000, menu))
68 })
69
70 t.Run("highest fee across menu entries", func(t *testing.T) {
71 menu := []ldk_node.Lsps2OpeningFeeParams{
72 makeLsps2OpeningFeeParams(10_000, 5_000, 1_000_000, 100_000_000),
73 makeLsps2OpeningFeeParams(10_000, 20_000, 1_000_000, 100_000_000),
74 }
75 assert.Equal(t, uint64(200_000), computeLsps2MaxTotalOpeningFeeMsat(10_000_000, menu))
76 })
77
78 t.Run("entries not covering the payment size are skipped", func(t *testing.T) {
79 menu := []ldk_node.Lsps2OpeningFeeParams{
80 makeLsps2OpeningFeeParams(10_000, 5_000, 1_000_000, 100_000_000),
81 // covers larger payments only, would otherwise win with 2%
82 makeLsps2OpeningFeeParams(10_000, 20_000, 20_000_000, 100_000_000),
83 }
84 assert.Equal(t, uint64(50_000), computeLsps2MaxTotalOpeningFeeMsat(10_000_000, menu))
85 })
86
87 t.Run("menu fee above ceiling is clamped to ceiling", func(t *testing.T) {
88 menu := []ldk_node.Lsps2OpeningFeeParams{
89 // 20% of 100M msat = 20M msat, above the 10% / 10M msat ceiling
90 makeLsps2OpeningFeeParams(5_000_000, 200_000, 1_000_000, 1_000_000_000),
91 }
92 assert.Equal(t, uint64(10_000_000), computeLsps2MaxTotalOpeningFeeMsat(100_000_000, menu))
93 })
94
95 t.Run("base ceiling applies when no entry covers the payment size", func(t *testing.T) {
96 menu := []ldk_node.Lsps2OpeningFeeParams{
97 makeLsps2OpeningFeeParams(10_000, 5_000, 1_000_000, 100_000_000),
98 }
99 // 10% of 200M msat = 20M msat
100 assert.Equal(t, uint64(20_000_000), computeLsps2MaxTotalOpeningFeeMsat(200_000_000, menu))
101 })
102
103 t.Run("base ceiling applies on empty menu", func(t *testing.T) {
104 assert.Equal(t, uint64(5_000_000), computeLsps2MaxTotalOpeningFeeMsat(10_000_000, nil))
105 })
106 }
107
108 func TestComputeLsps2MinPaymentSizeMsat(t *testing.T) {
109 t.Run("minimum fee below ceiling base", func(t *testing.T) {
110 // 1000 sat minimum fee: smallest usable payment nets 1 sat above the fee
111 params := makeLsps2OpeningFeeParams(1_000_000, 10_000, 1_000, 100_000_000_000)
112 minPaymentSizeMsat, ok := computeLsps2MinPaymentSizeMsat(params)
113 require.True(t, ok)
114 assert.Equal(t, uint64(1_001_000), minPaymentSizeMsat)
115 })
116
117 t.Run("minimum fee above ceiling base", func(t *testing.T) {
118 // 8000 sat minimum fee exceeds the 5000 sat ceiling base, so the
119 // smallest payment is where the fee equals 10% of the payment
120 params := makeLsps2OpeningFeeParams(8_000_000, 10_000, 1_000, 100_000_000_000)
121 minPaymentSizeMsat, ok := computeLsps2MinPaymentSizeMsat(params)
122 require.True(t, ok)
123 assert.Equal(t, uint64(80_000_000), minPaymentSizeMsat)
124 })
125
126 t.Run("proportional fee above ceiling percentage never fits", func(t *testing.T) {
127 // 30% proportional fee with a minimum fee above the ceiling base can
128 // never satisfy the 10% ceiling
129 params := makeLsps2OpeningFeeParams(6_000_000, 300_000, 1_000, 1_000_000_000)
130 _, ok := computeLsps2MinPaymentSizeMsat(params)
131 assert.False(t, ok)
132 })
133 }
134
135 func TestSanitizeChainEndpointForBitcoind(t *testing.T) {
136 tests := []struct {
137 name string
138 endpoint string
139 rpcPort string
140 expected string
141 }{
142 {
143 name: "adds configured port to host",
144 endpoint: "127.0.0.1",
145 rpcPort: "8332",
146 expected: "127.0.0.1:8332",
147 },
148 {
149 name: "preserves endpoint port",
150 endpoint: "127.0.0.1:18443",
151 rpcPort: "8332",
152 expected: "127.0.0.1:18443",
153 },
154 {
155 name: "formats ipv6 host",
156 endpoint: "[2001:db8::1]",
157 rpcPort: "8332",
158 expected: "[2001:db8::1]:8332",
159 },
160 {
161 name: "strips credentials from url-shaped input",
162 endpoint: "user:pass@[2001:db8::1]:18443",
163 rpcPort: "8332",
164 expected: "[2001:db8::1]:18443",
165 },
166 }
167
168 for _, tt := range tests {
169 t.Run(tt.name, func(t *testing.T) {
170 assert.Equal(t, tt.expected, sanitizeChainEndpoint(tt.endpoint, tt.rpcPort))
171 })
172 }
173 }
174
175 func TestSanitizeChainEndpointForURLs(t *testing.T) {
176 tests := []struct {
177 name string
178 endpoint string
179 expected string
180 }{
181 {
182 name: "keeps bare electrum endpoint unchanged",
183 endpoint: "electrum.example.com:50002",
184 expected: "electrum.example.com:50002",
185 },
186 {
187 name: "strips url credentials",
188 endpoint: "ssl://user:pass@electrum.example.com:50002",
189 expected: "ssl://electrum.example.com:50002",
190 },
191 {
192 name: "strips esplora credentials",
193 endpoint: "https://user:pass@esplora.example.com/api",
194 expected: "https://esplora.example.com/api",
195 },
196 }
197
198 for _, tt := range tests {
199 t.Run(tt.name, func(t *testing.T) {
200 assert.Equal(t, tt.expected, sanitizeChainEndpoint(tt.endpoint, ""))
201 })
202 }
203 }
204