Skip to content

Commit eb7b771

Browse files
authored
Merge pull request #1089 from lightninglabs/keysend-one-sat
channels: create test cases for two new bug fixes
2 parents 25ac374 + 6c5f6b1 commit eb7b771

File tree

7 files changed

+113
-13
lines changed

7 files changed

+113
-13
lines changed

docs/release-notes/release-notes-0.15.0.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@
9595
### Taproot Assets
9696

9797
* Updated [`tapd` to
98-
`v0.6.0-rc3`](https://github.com/lightninglabs/lightning-terminal/pull/1082).
98+
`v0.6.0`](https://github.com/lightninglabs/lightning-terminal/pull/1089).
9999
* All Taproot Asset Channel related commands (`litcli ln ...`) can now [use
100100
a new `--group_key` flag to interact with grouped asset
101101
channels](https://github.com/lightninglabs/lightning-terminal/pull/1052).

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ require (
3232
github.com/lightninglabs/pool v0.6.6-beta
3333
github.com/lightninglabs/pool/auctioneerrpc v1.1.3
3434
github.com/lightninglabs/pool/poolrpc v1.0.1
35-
github.com/lightninglabs/taproot-assets v0.6.0-rc3
36-
github.com/lightninglabs/taproot-assets/taprpc v1.0.6
35+
github.com/lightninglabs/taproot-assets v0.6.0
36+
github.com/lightninglabs/taproot-assets/taprpc v1.0.7
3737
github.com/lightningnetwork/lnd v0.19.1-beta.rc1
3838
github.com/lightningnetwork/lnd/cert v1.2.2
3939
github.com/lightningnetwork/lnd/clock v1.1.1

go.sum

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,10 +1172,10 @@ github.com/lightninglabs/pool/poolrpc v1.0.1 h1:XbNx28TYwEj/PVsnnF9TnveVCMCYfS1v
11721172
github.com/lightninglabs/pool/poolrpc v1.0.1/go.mod h1:836icifg/SBnZbiae0v3jeRRzCrT6LWo32SqCS/JiGk=
11731173
github.com/lightninglabs/protobuf-go-hex-display v1.34.2-hex-display h1:w7FM5LH9Z6CpKxl13mS48idsu6F+cEZf0lkyiV+Dq9g=
11741174
github.com/lightninglabs/protobuf-go-hex-display v1.34.2-hex-display/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
1175-
github.com/lightninglabs/taproot-assets v0.6.0-rc3 h1:LLHmxeIcpiVcWxGL8DwZxn6LYjeowwwDbOSEEl1EdBA=
1176-
github.com/lightninglabs/taproot-assets v0.6.0-rc3/go.mod h1:38uM/4StASo1coMGPEab2vHPhfOjoQj0zCMgzPtNCgE=
1177-
github.com/lightninglabs/taproot-assets/taprpc v1.0.6 h1:h8tf4y7U5/3A9WNAs7HBTL8Vhgk/FT2JP2NldpwTaHE=
1178-
github.com/lightninglabs/taproot-assets/taprpc v1.0.6/go.mod h1:vOM2Ap2wYhEZjiJU7bNNg+e5tDxkvRAuyXwf/KQ4tgo=
1175+
github.com/lightninglabs/taproot-assets v0.6.0 h1:nHloX+QR2PbUmogry1T+LiYh1TWBoFnTMHOy4Hyq1VM=
1176+
github.com/lightninglabs/taproot-assets v0.6.0/go.mod h1:CkK0drLPo5M6ib9YRE3lD+znOfe0Oxh6zMvGN1SJXDo=
1177+
github.com/lightninglabs/taproot-assets/taprpc v1.0.7 h1:yUG9vdpajiU0gp4wDkTPz/6BI8Vr52OM2paahlVrAys=
1178+
github.com/lightninglabs/taproot-assets/taprpc v1.0.7/go.mod h1:vOM2Ap2wYhEZjiJU7bNNg+e5tDxkvRAuyXwf/KQ4tgo=
11791179
github.com/lightningnetwork/lightning-onion v1.2.1-0.20240712235311-98bd56499dfb h1:yfM05S8DXKhuCBp5qSMZdtSwvJ+GFzl94KbXMNB1JDY=
11801180
github.com/lightningnetwork/lightning-onion v1.2.1-0.20240712235311-98bd56499dfb/go.mod h1:c0kvRShutpj3l6B9WtTsNTBUtjSmjZXbJd9ZBRQOSKI=
11811181
github.com/lightningnetwork/lnd v0.19.1-beta.rc1 h1:VV7xpS1g7OpDhlGYIa50Ac4I7TDZhvHjZ2Mmf+L4a7Y=

itest/assets_test.go

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1364,7 +1364,12 @@ func sendAssetKeySendPayment(t *testing.T, src, dst *HarnessNode, amt uint64,
13641364
}
13651365

13661366
func sendKeySendPayment(t *testing.T, src, dst *HarnessNode,
1367-
amt btcutil.Amount) {
1367+
amt btcutil.Amount, opts ...payOpt) {
1368+
1369+
cfg := defaultPayConfig()
1370+
for _, opt := range opts {
1371+
opt(cfg)
1372+
}
13681373

13691374
ctxb := context.Background()
13701375
ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout)
@@ -1382,12 +1387,21 @@ func sendKeySendPayment(t *testing.T, src, dst *HarnessNode,
13821387
customRecords := make(map[uint64][]byte)
13831388
customRecords[record.KeySendType] = preimage[:]
13841389

1390+
for key, value := range cfg.destCustomRecords {
1391+
customRecords[key] = value
1392+
}
1393+
13851394
req := &routerrpc.SendPaymentRequest{
13861395
Dest: dst.PubKey[:],
13871396
Amt: int64(amt),
13881397
DestCustomRecords: customRecords,
13891398
PaymentHash: hash[:],
13901399
TimeoutSeconds: int32(PaymentTimeout.Seconds()),
1400+
FeeLimitMsat: int64(cfg.feeLimit),
1401+
MaxParts: cfg.maxShards,
1402+
OutgoingChanIds: cfg.outgoingChanIDs,
1403+
AllowSelfPayment: cfg.allowSelfPayment,
1404+
RouteHints: cfg.routeHints,
13911405
}
13921406

13931407
stream, err := src.RouterClient.SendPaymentV2(ctxt, req)
@@ -1463,7 +1477,7 @@ func payPayReqWithSatoshi(t *testing.T, payer *HarnessNode, payReq string,
14631477
sendReq := &routerrpc.SendPaymentRequest{
14641478
PaymentRequest: payReq,
14651479
TimeoutSeconds: int32(PaymentTimeout.Seconds()),
1466-
FeeLimitMsat: 1_000_000,
1480+
FeeLimitMsat: int64(cfg.feeLimit),
14671481
MaxParts: cfg.maxShards,
14681482
OutgoingChanIds: cfg.outgoingChanIDs,
14691483
AllowSelfPayment: cfg.allowSelfPayment,
@@ -1548,6 +1562,7 @@ type payConfig struct {
15481562
groupKey []byte
15491563
outgoingChanIDs []uint64
15501564
allowSelfPayment bool
1565+
routeHints []*lnrpc.RouteHint
15511566
}
15521567

15531568
func defaultPayConfig() *payConfig {
@@ -1631,6 +1646,12 @@ func withAllowSelfPayment() payOpt {
16311646
}
16321647
}
16331648

1649+
func withPayRouteHints(hints []*lnrpc.RouteHint) payOpt {
1650+
return func(c *payConfig) {
1651+
c.routeHints = hints
1652+
}
1653+
}
1654+
16341655
func payInvoiceWithAssets(t *testing.T, payer, rfqPeer *HarnessNode,
16351656
payReq string, assetID []byte,
16361657
opts ...payOpt) (uint64, rfqmath.BigIntFixedPoint) {

itest/litd_custom_channels_test.go

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2389,7 +2389,7 @@ func testCustomChannelsLiquidityEdgeCasesCore(ctx context.Context,
23892389
)
23902390
charlieFundingAmount := cents.Amount - uint64(2*400_000)
23912391

2392-
_, _, _ = createTestAssetNetwork(
2392+
_, _, chanPointEF := createTestAssetNetwork(
23932393
t, net, charlieTap, daveTap, erinTap, fabiaTap, yaraTap,
23942394
universeTap, cents, 400_000, charlieFundingAmount,
23952395
daveFundingAmount, erinFundingAmount, 0,
@@ -2407,6 +2407,37 @@ func testCustomChannelsLiquidityEdgeCasesCore(ctx context.Context,
24072407

24082408
logBalance(t.t, nodes, assetID, "initial")
24092409

2410+
// Edge case: We send a single satoshi keysend payment from Dave to
2411+
// Fabia. Which will make it so that Fabia's balance in the channel
2412+
// between Erin and her is 1 satoshi, which is below the dust limit.
2413+
// This is only allowed while Fabia doesn't have any assets on her side
2414+
// yet.
2415+
erinFabiaChan := fetchChannel(t.t, fabia, chanPointEF)
2416+
hinEF := &lnrpc.HopHint{
2417+
NodeId: erin.PubKeyStr,
2418+
ChanId: erinFabiaChan.PeerScidAlias,
2419+
CltvExpiryDelta: 80,
2420+
FeeBaseMsat: 1000,
2421+
FeeProportionalMillionths: 1,
2422+
}
2423+
sendKeySendPayment(
2424+
t.t, dave, fabia, 1, withPayRouteHints([]*lnrpc.RouteHint{{
2425+
HopHints: []*lnrpc.HopHint{hinEF},
2426+
}}),
2427+
)
2428+
logBalance(t.t, nodes, assetID, "after single sat keysend")
2429+
2430+
// We make sure that a single sat keysend payment is not allowed when
2431+
// it carries assets.
2432+
sendAssetKeySendPayment(
2433+
t.t, erin, fabia, 123, assetID, fn.Some[int64](1),
2434+
withPayErrSubStr(
2435+
fmt.Sprintf("keysend payment satoshi amount must be "+
2436+
"greater than or equal to %d satoshis",
2437+
rfqmath.DefaultOnChainHtlcSat),
2438+
),
2439+
)
2440+
24102441
// Normal case.
24112442
// Send 50 assets from Charlie to Dave.
24122443
sendAssetKeySendPayment(
@@ -2870,6 +2901,54 @@ func testCustomChannelsLiquidityEdgeCasesCore(ctx context.Context,
28702901
)
28712902

28722903
logBalance(t.t, nodes, assetID, "after safe asset htlc failure")
2904+
2905+
// Another test case: Make sure an asset invoice contains the correct
2906+
// channel policy. We expect it to be the policy for the direction from
2907+
// edge node to receiver node. To test this, we first set two different
2908+
// policies on the channel between Erin and Fabia.
2909+
resp, err := erin.UpdateChannelPolicy(ctx, &lnrpc.PolicyUpdateRequest{
2910+
Scope: &lnrpc.PolicyUpdateRequest_ChanPoint{
2911+
ChanPoint: chanPointEF,
2912+
},
2913+
BaseFeeMsat: 31337,
2914+
FeeRatePpm: 443322,
2915+
TimeLockDelta: 19,
2916+
})
2917+
require.NoError(t.t, err)
2918+
require.Empty(t.t, resp.FailedUpdates)
2919+
2920+
resp, err = fabia.UpdateChannelPolicy(ctx, &lnrpc.PolicyUpdateRequest{
2921+
Scope: &lnrpc.PolicyUpdateRequest_ChanPoint{
2922+
ChanPoint: chanPointEF,
2923+
},
2924+
BaseFeeMsat: 42069,
2925+
FeeRatePpm: 223344,
2926+
TimeLockDelta: 18,
2927+
})
2928+
require.NoError(t.t, err)
2929+
require.Empty(t.t, resp.FailedUpdates)
2930+
2931+
// We now create an invoice on Fabia and expect Erin's policy to be used
2932+
// in the invoice.
2933+
invoiceResp = createAssetInvoice(t.t, erin, fabia, 1_000, assetID)
2934+
req, err := erin.DecodePayReq(ctx, &lnrpc.PayReqString{
2935+
PayReq: invoiceResp.PaymentRequest,
2936+
})
2937+
require.NoError(t.t, err)
2938+
2939+
require.Len(t.t, req.RouteHints, 1)
2940+
require.Len(t.t, req.RouteHints[0].HopHints, 1)
2941+
invoiceHint := req.RouteHints[0].HopHints[0]
2942+
require.Equal(t.t, erin.PubKeyStr, invoiceHint.NodeId)
2943+
require.EqualValues(t.t, 31337, invoiceHint.FeeBaseMsat)
2944+
require.EqualValues(t.t, 443322, invoiceHint.FeeProportionalMillionths)
2945+
require.EqualValues(t.t, 19, invoiceHint.CltvExpiryDelta)
2946+
2947+
// Now we pay the invoice and expect the same policy with very expensive
2948+
// fees to be used.
2949+
payInvoiceWithSatoshi(
2950+
t.t, dave, invoiceResp, withFeeLimit(100_000_000),
2951+
)
28732952
}
28742953

28752954
// testCustomChannelsLiquidityEdgeCases is a test that runs through some

litrpc/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ require (
77
github.com/lightninglabs/faraday/frdrpc v1.0.0
88
github.com/lightninglabs/loop/looprpc v1.0.0
99
github.com/lightninglabs/pool/poolrpc v1.0.0
10-
github.com/lightninglabs/taproot-assets/taprpc v1.0.5-0.20250526115916-1ac1deab2f9b
10+
github.com/lightninglabs/taproot-assets/taprpc v1.0.7
1111
github.com/lightningnetwork/lnd v0.19.0-beta
1212
google.golang.org/grpc v1.65.0
1313
google.golang.org/protobuf v1.34.2

litrpc/go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,8 +1102,8 @@ github.com/lightninglabs/pool/poolrpc v1.0.0 h1:vvosrgNx9WXF4mcHGqLjZOW8wNM0q+BL
11021102
github.com/lightninglabs/pool/poolrpc v1.0.0/go.mod h1:ZqpEpBFRMMBAerMmilEjh27tqauSXDwLaLR0O3jvmMA=
11031103
github.com/lightninglabs/protobuf-go-hex-display v1.34.2-hex-display h1:w7FM5LH9Z6CpKxl13mS48idsu6F+cEZf0lkyiV+Dq9g=
11041104
github.com/lightninglabs/protobuf-go-hex-display v1.34.2-hex-display/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
1105-
github.com/lightninglabs/taproot-assets/taprpc v1.0.5-0.20250526115916-1ac1deab2f9b h1:XmIJhYwUZ75BiZPXhsutwlgTin35QSjn+KhYbuPtHkQ=
1106-
github.com/lightninglabs/taproot-assets/taprpc v1.0.5-0.20250526115916-1ac1deab2f9b/go.mod h1:vOM2Ap2wYhEZjiJU7bNNg+e5tDxkvRAuyXwf/KQ4tgo=
1105+
github.com/lightninglabs/taproot-assets/taprpc v1.0.7 h1:yUG9vdpajiU0gp4wDkTPz/6BI8Vr52OM2paahlVrAys=
1106+
github.com/lightninglabs/taproot-assets/taprpc v1.0.7/go.mod h1:vOM2Ap2wYhEZjiJU7bNNg+e5tDxkvRAuyXwf/KQ4tgo=
11071107
github.com/lightningnetwork/lightning-onion v1.2.1-0.20240712235311-98bd56499dfb h1:yfM05S8DXKhuCBp5qSMZdtSwvJ+GFzl94KbXMNB1JDY=
11081108
github.com/lightningnetwork/lightning-onion v1.2.1-0.20240712235311-98bd56499dfb/go.mod h1:c0kvRShutpj3l6B9WtTsNTBUtjSmjZXbJd9ZBRQOSKI=
11091109
github.com/lightningnetwork/lnd v0.19.0-beta h1:/8i2UdARiEpI2iAmPoSDcwZSSEuWqXyfsMxz/mLGbdw=

0 commit comments

Comments
 (0)