Skip to content

Commit d3e915a

Browse files
committed
itest: test imported address in coop close
Make sure that an address imported to LND via ImportTapscript or ImportPublicKey can be used as a delivery address in coop close. New test cases: - P2TR address imported with ImportTapscript - P2TR address imported with ImportPublicKey - P2WPKH address imported with ImportPublicKey Safeguard against lightninglabs/loop#923
1 parent f2c3eef commit d3e915a

File tree

1 file changed

+149
-11
lines changed

1 file changed

+149
-11
lines changed

itest/lnd_coop_close_external_delivery_test.go

Lines changed: 149 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import (
44
"fmt"
55

66
"github.com/btcsuite/btcd/btcutil"
7+
"github.com/btcsuite/btcd/txscript"
78
"github.com/lightningnetwork/lnd/lnrpc"
9+
"github.com/lightningnetwork/lnd/lnrpc/walletrpc"
810
"github.com/lightningnetwork/lnd/lntest"
911
"github.com/lightningnetwork/lnd/lntest/wait"
1012
"github.com/stretchr/testify/require"
@@ -15,7 +17,7 @@ var coopCloseWithExternalTestCases = []*lntest.TestCase{
1517
Name: "set P2WPKH delivery address at open",
1618
TestFunc: func(ht *lntest.HarnessTest) {
1719
testCoopCloseWithExternalDelivery(
18-
ht, true,
20+
ht, true, false, false,
1921
lnrpc.AddressType_UNUSED_WITNESS_PUBKEY_HASH,
2022
)
2123
},
@@ -24,7 +26,7 @@ var coopCloseWithExternalTestCases = []*lntest.TestCase{
2426
Name: "set P2WPKH delivery address at close",
2527
TestFunc: func(ht *lntest.HarnessTest) {
2628
testCoopCloseWithExternalDelivery(
27-
ht, false,
29+
ht, false, false, false,
2830
lnrpc.AddressType_UNUSED_WITNESS_PUBKEY_HASH,
2931
)
3032
},
@@ -33,7 +35,7 @@ var coopCloseWithExternalTestCases = []*lntest.TestCase{
3335
Name: "set P2TR delivery address at open",
3436
TestFunc: func(ht *lntest.HarnessTest) {
3537
testCoopCloseWithExternalDelivery(
36-
ht, true,
38+
ht, true, false, false,
3739
lnrpc.AddressType_UNUSED_TAPROOT_PUBKEY,
3840
)
3941
},
@@ -42,7 +44,61 @@ var coopCloseWithExternalTestCases = []*lntest.TestCase{
4244
Name: "set P2TR delivery address at close",
4345
TestFunc: func(ht *lntest.HarnessTest) {
4446
testCoopCloseWithExternalDelivery(
45-
ht, false,
47+
ht, false, false, false,
48+
lnrpc.AddressType_UNUSED_TAPROOT_PUBKEY,
49+
)
50+
},
51+
},
52+
{
53+
Name: "set imported P2TR address (ImportTapscript) at open",
54+
TestFunc: func(ht *lntest.HarnessTest) {
55+
testCoopCloseWithExternalDelivery(
56+
ht, true, true, false,
57+
lnrpc.AddressType_UNUSED_TAPROOT_PUBKEY,
58+
)
59+
},
60+
},
61+
{
62+
Name: "set imported P2TR address (ImportTapscript) at close",
63+
TestFunc: func(ht *lntest.HarnessTest) {
64+
testCoopCloseWithExternalDelivery(
65+
ht, false, true, false,
66+
lnrpc.AddressType_UNUSED_TAPROOT_PUBKEY,
67+
)
68+
},
69+
},
70+
{
71+
Name: "set imported P2WPKH address at open",
72+
TestFunc: func(ht *lntest.HarnessTest) {
73+
testCoopCloseWithExternalDelivery(
74+
ht, true, false, true,
75+
lnrpc.AddressType_UNUSED_WITNESS_PUBKEY_HASH,
76+
)
77+
},
78+
},
79+
{
80+
Name: "set imported P2WPKH address at close",
81+
TestFunc: func(ht *lntest.HarnessTest) {
82+
testCoopCloseWithExternalDelivery(
83+
ht, false, false, true,
84+
lnrpc.AddressType_UNUSED_WITNESS_PUBKEY_HASH,
85+
)
86+
},
87+
},
88+
{
89+
Name: "set imported P2TR address (ImportPublicKey) at open",
90+
TestFunc: func(ht *lntest.HarnessTest) {
91+
testCoopCloseWithExternalDelivery(
92+
ht, true, false, true,
93+
lnrpc.AddressType_UNUSED_TAPROOT_PUBKEY,
94+
)
95+
},
96+
},
97+
{
98+
Name: "set imported P2TR address (ImportPublicKey) at close",
99+
TestFunc: func(ht *lntest.HarnessTest) {
100+
testCoopCloseWithExternalDelivery(
101+
ht, false, false, true,
46102
lnrpc.AddressType_UNUSED_TAPROOT_PUBKEY,
47103
)
48104
},
@@ -53,20 +109,102 @@ var coopCloseWithExternalTestCases = []*lntest.TestCase{
53109
// balance irrespective of whether the delivery address is in LND's wallet or
54110
// not. Some users set this value to be an address in a different wallet and
55111
// this should not affect our ability to accurately report the settled balance.
112+
//
113+
// If importTapscript is set, it imports a Taproot script and internal key to
114+
// Alice's LND using ImportTapscript to make sure it doesn't interfere with
115+
// delivery address. If importPubkey is set, the address is imported using
116+
// ImportPublicKey.
56117
func testCoopCloseWithExternalDelivery(ht *lntest.HarnessTest,
57-
upfrontShutdown bool, deliveryAddressType lnrpc.AddressType) {
118+
upfrontShutdown, importTapscript, importPubkey bool,
119+
deliveryAddressType lnrpc.AddressType) {
58120

59121
alice := ht.NewNodeWithCoins("Alice", nil)
60122
bob := ht.NewNodeWithCoins("bob", nil)
61123
ht.ConnectNodes(alice, bob)
62124

125+
// Make fake taproot internal public key (equal to the final).
126+
// This is only used if importTapscript or importPubkey is set.
127+
taprootPubkey := [32]byte{1, 2, 3}
128+
if upfrontShutdown {
129+
// Make new address for second sub-test not to import
130+
// the same address twice causing an error.
131+
taprootPubkey[3] = 1
132+
}
133+
pkScriptBytes := append(
134+
[]byte{txscript.OP_1, txscript.OP_DATA_32},
135+
taprootPubkey[:]...,
136+
)
137+
pkScript, err := txscript.ParsePkScript(pkScriptBytes)
138+
require.NoError(ht, err)
139+
taprootAddress, err := pkScript.Address(harnessNetParams)
140+
require.NoError(ht, err)
141+
142+
var addr string
143+
switch {
144+
// Use ImportTapscript.
145+
case importTapscript:
146+
addr = taprootAddress.String()
147+
148+
// Import the taproot address to LND.
149+
req := &walletrpc.ImportTapscriptRequest{
150+
InternalPublicKey: taprootPubkey[:],
151+
Script: &walletrpc.ImportTapscriptRequest_FullKeyOnly{
152+
FullKeyOnly: true,
153+
},
154+
}
155+
res := alice.RPC.ImportTapscript(req)
156+
require.Equal(ht, addr, res.P2TrAddress)
157+
158+
// Use ImportPublicKey.
159+
case importPubkey:
160+
var (
161+
address btcutil.Address
162+
pubKey []byte
163+
addressType walletrpc.AddressType
164+
)
165+
switch deliveryAddressType {
166+
case lnrpc.AddressType_UNUSED_WITNESS_PUBKEY_HASH:
167+
// Make fake public key hash.
168+
pk := [33]byte{2, 3, 4}
169+
if upfrontShutdown {
170+
// Make new address for second sub-test.
171+
pk[1]++
172+
}
173+
address, err = btcutil.NewAddressWitnessPubKeyHash(
174+
btcutil.Hash160(pk[:]), harnessNetParams,
175+
)
176+
require.NoError(ht, err)
177+
pubKey = pk[:]
178+
addressType = walletrpc.AddressType_WITNESS_PUBKEY_HASH
179+
180+
case lnrpc.AddressType_UNUSED_TAPROOT_PUBKEY:
181+
address = taprootAddress
182+
pubKey = taprootPubkey[:]
183+
addressType = walletrpc.AddressType_TAPROOT_PUBKEY
184+
185+
default:
186+
ht.Fatalf("not allowed address type: %v",
187+
deliveryAddressType)
188+
}
189+
190+
addr = address.String()
191+
192+
// Import the address to LND.
193+
alice.RPC.ImportPublicKey(&walletrpc.ImportPublicKeyRequest{
194+
PublicKey: pubKey,
195+
AddressType: addressType,
196+
})
197+
63198
// Here we generate a final delivery address in bob's wallet but set by
64199
// alice. We do this to ensure that the address is not in alice's LND
65200
// wallet. We already correctly track settled balances when the address
66201
// is in the LND wallet.
67-
addr := bob.RPC.NewAddress(&lnrpc.NewAddressRequest{
68-
Type: deliveryAddressType,
69-
})
202+
default:
203+
res := bob.RPC.NewAddress(&lnrpc.NewAddressRequest{
204+
Type: deliveryAddressType,
205+
})
206+
addr = res.Address
207+
}
70208

71209
// Prepare for channel open.
72210
openParams := lntest.OpenChannelParams{
@@ -76,7 +214,7 @@ func testCoopCloseWithExternalDelivery(ht *lntest.HarnessTest,
76214
// If we are testing the case where we set it on open then we'll set the
77215
// upfront shutdown script in the channel open parameters.
78216
if upfrontShutdown {
79-
openParams.CloseAddress = addr.Address
217+
openParams.CloseAddress = addr
80218
}
81219

82220
// Open the channel!
@@ -91,14 +229,14 @@ func testCoopCloseWithExternalDelivery(ht *lntest.HarnessTest,
91229
// If we are testing the case where we set the delivery address on
92230
// channel close then we will set it in the channel close parameters.
93231
if !upfrontShutdown {
94-
closeParams.DeliveryAddress = addr.Address
232+
closeParams.DeliveryAddress = addr
95233
}
96234

97235
// Close the channel!
98236
closeClient := alice.RPC.CloseChannel(&closeParams)
99237

100238
// Assert that we got a channel update when we get a closing txid.
101-
_, err := closeClient.Recv()
239+
_, err = closeClient.Recv()
102240
require.NoError(ht, err)
103241

104242
// Mine the closing transaction.

0 commit comments

Comments
 (0)