diff --git a/docs/release-notes/release-notes-0.15.0.md b/docs/release-notes/release-notes-0.15.0.md index e6308dd55..38a6ab518 100644 --- a/docs/release-notes/release-notes-0.15.0.md +++ b/docs/release-notes/release-notes-0.15.0.md @@ -95,7 +95,7 @@ ### Taproot Assets * Updated [`tapd` to - `v0.6.0-rc3`](https://github.com/lightninglabs/lightning-terminal/pull/1082). + `v0.6.0`](https://github.com/lightninglabs/lightning-terminal/pull/1089). * All Taproot Asset Channel related commands (`litcli ln ...`) can now [use a new `--group_key` flag to interact with grouped asset channels](https://github.com/lightninglabs/lightning-terminal/pull/1052). diff --git a/go.mod b/go.mod index c0a0c05c5..a03bbdba4 100644 --- a/go.mod +++ b/go.mod @@ -32,8 +32,8 @@ require ( github.com/lightninglabs/pool v0.6.6-beta github.com/lightninglabs/pool/auctioneerrpc v1.1.3 github.com/lightninglabs/pool/poolrpc v1.0.1 - github.com/lightninglabs/taproot-assets v0.6.0-rc3 - github.com/lightninglabs/taproot-assets/taprpc v1.0.6 + github.com/lightninglabs/taproot-assets v0.6.0 + github.com/lightninglabs/taproot-assets/taprpc v1.0.7 github.com/lightningnetwork/lnd v0.19.1-beta.rc1 github.com/lightningnetwork/lnd/cert v1.2.2 github.com/lightningnetwork/lnd/clock v1.1.1 diff --git a/go.sum b/go.sum index 36adbb9e0..c5587ec8a 100644 --- a/go.sum +++ b/go.sum @@ -1172,10 +1172,10 @@ github.com/lightninglabs/pool/poolrpc v1.0.1 h1:XbNx28TYwEj/PVsnnF9TnveVCMCYfS1v github.com/lightninglabs/pool/poolrpc v1.0.1/go.mod h1:836icifg/SBnZbiae0v3jeRRzCrT6LWo32SqCS/JiGk= github.com/lightninglabs/protobuf-go-hex-display v1.34.2-hex-display h1:w7FM5LH9Z6CpKxl13mS48idsu6F+cEZf0lkyiV+Dq9g= github.com/lightninglabs/protobuf-go-hex-display v1.34.2-hex-display/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= -github.com/lightninglabs/taproot-assets v0.6.0-rc3 h1:LLHmxeIcpiVcWxGL8DwZxn6LYjeowwwDbOSEEl1EdBA= -github.com/lightninglabs/taproot-assets v0.6.0-rc3/go.mod h1:38uM/4StASo1coMGPEab2vHPhfOjoQj0zCMgzPtNCgE= -github.com/lightninglabs/taproot-assets/taprpc v1.0.6 h1:h8tf4y7U5/3A9WNAs7HBTL8Vhgk/FT2JP2NldpwTaHE= -github.com/lightninglabs/taproot-assets/taprpc v1.0.6/go.mod h1:vOM2Ap2wYhEZjiJU7bNNg+e5tDxkvRAuyXwf/KQ4tgo= +github.com/lightninglabs/taproot-assets v0.6.0 h1:nHloX+QR2PbUmogry1T+LiYh1TWBoFnTMHOy4Hyq1VM= +github.com/lightninglabs/taproot-assets v0.6.0/go.mod h1:CkK0drLPo5M6ib9YRE3lD+znOfe0Oxh6zMvGN1SJXDo= +github.com/lightninglabs/taproot-assets/taprpc v1.0.7 h1:yUG9vdpajiU0gp4wDkTPz/6BI8Vr52OM2paahlVrAys= +github.com/lightninglabs/taproot-assets/taprpc v1.0.7/go.mod h1:vOM2Ap2wYhEZjiJU7bNNg+e5tDxkvRAuyXwf/KQ4tgo= github.com/lightningnetwork/lightning-onion v1.2.1-0.20240712235311-98bd56499dfb h1:yfM05S8DXKhuCBp5qSMZdtSwvJ+GFzl94KbXMNB1JDY= github.com/lightningnetwork/lightning-onion v1.2.1-0.20240712235311-98bd56499dfb/go.mod h1:c0kvRShutpj3l6B9WtTsNTBUtjSmjZXbJd9ZBRQOSKI= github.com/lightningnetwork/lnd v0.19.1-beta.rc1 h1:VV7xpS1g7OpDhlGYIa50Ac4I7TDZhvHjZ2Mmf+L4a7Y= diff --git a/itest/assets_test.go b/itest/assets_test.go index b6786878f..1fb456dac 100644 --- a/itest/assets_test.go +++ b/itest/assets_test.go @@ -1364,7 +1364,12 @@ func sendAssetKeySendPayment(t *testing.T, src, dst *HarnessNode, amt uint64, } func sendKeySendPayment(t *testing.T, src, dst *HarnessNode, - amt btcutil.Amount) { + amt btcutil.Amount, opts ...payOpt) { + + cfg := defaultPayConfig() + for _, opt := range opts { + opt(cfg) + } ctxb := context.Background() ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout) @@ -1382,12 +1387,21 @@ func sendKeySendPayment(t *testing.T, src, dst *HarnessNode, customRecords := make(map[uint64][]byte) customRecords[record.KeySendType] = preimage[:] + for key, value := range cfg.destCustomRecords { + customRecords[key] = value + } + req := &routerrpc.SendPaymentRequest{ Dest: dst.PubKey[:], Amt: int64(amt), DestCustomRecords: customRecords, PaymentHash: hash[:], TimeoutSeconds: int32(PaymentTimeout.Seconds()), + FeeLimitMsat: int64(cfg.feeLimit), + MaxParts: cfg.maxShards, + OutgoingChanIds: cfg.outgoingChanIDs, + AllowSelfPayment: cfg.allowSelfPayment, + RouteHints: cfg.routeHints, } stream, err := src.RouterClient.SendPaymentV2(ctxt, req) @@ -1463,7 +1477,7 @@ func payPayReqWithSatoshi(t *testing.T, payer *HarnessNode, payReq string, sendReq := &routerrpc.SendPaymentRequest{ PaymentRequest: payReq, TimeoutSeconds: int32(PaymentTimeout.Seconds()), - FeeLimitMsat: 1_000_000, + FeeLimitMsat: int64(cfg.feeLimit), MaxParts: cfg.maxShards, OutgoingChanIds: cfg.outgoingChanIDs, AllowSelfPayment: cfg.allowSelfPayment, @@ -1548,6 +1562,7 @@ type payConfig struct { groupKey []byte outgoingChanIDs []uint64 allowSelfPayment bool + routeHints []*lnrpc.RouteHint } func defaultPayConfig() *payConfig { @@ -1631,6 +1646,12 @@ func withAllowSelfPayment() payOpt { } } +func withPayRouteHints(hints []*lnrpc.RouteHint) payOpt { + return func(c *payConfig) { + c.routeHints = hints + } +} + func payInvoiceWithAssets(t *testing.T, payer, rfqPeer *HarnessNode, payReq string, assetID []byte, opts ...payOpt) (uint64, rfqmath.BigIntFixedPoint) { diff --git a/itest/litd_custom_channels_test.go b/itest/litd_custom_channels_test.go index f6b746fa7..7a23314fb 100644 --- a/itest/litd_custom_channels_test.go +++ b/itest/litd_custom_channels_test.go @@ -2389,7 +2389,7 @@ func testCustomChannelsLiquidityEdgeCasesCore(ctx context.Context, ) charlieFundingAmount := cents.Amount - uint64(2*400_000) - _, _, _ = createTestAssetNetwork( + _, _, chanPointEF := createTestAssetNetwork( t, net, charlieTap, daveTap, erinTap, fabiaTap, yaraTap, universeTap, cents, 400_000, charlieFundingAmount, daveFundingAmount, erinFundingAmount, 0, @@ -2407,6 +2407,37 @@ func testCustomChannelsLiquidityEdgeCasesCore(ctx context.Context, logBalance(t.t, nodes, assetID, "initial") + // Edge case: We send a single satoshi keysend payment from Dave to + // Fabia. Which will make it so that Fabia's balance in the channel + // between Erin and her is 1 satoshi, which is below the dust limit. + // This is only allowed while Fabia doesn't have any assets on her side + // yet. + erinFabiaChan := fetchChannel(t.t, fabia, chanPointEF) + hinEF := &lnrpc.HopHint{ + NodeId: erin.PubKeyStr, + ChanId: erinFabiaChan.PeerScidAlias, + CltvExpiryDelta: 80, + FeeBaseMsat: 1000, + FeeProportionalMillionths: 1, + } + sendKeySendPayment( + t.t, dave, fabia, 1, withPayRouteHints([]*lnrpc.RouteHint{{ + HopHints: []*lnrpc.HopHint{hinEF}, + }}), + ) + logBalance(t.t, nodes, assetID, "after single sat keysend") + + // We make sure that a single sat keysend payment is not allowed when + // it carries assets. + sendAssetKeySendPayment( + t.t, erin, fabia, 123, assetID, fn.Some[int64](1), + withPayErrSubStr( + fmt.Sprintf("keysend payment satoshi amount must be "+ + "greater than or equal to %d satoshis", + rfqmath.DefaultOnChainHtlcSat), + ), + ) + // Normal case. // Send 50 assets from Charlie to Dave. sendAssetKeySendPayment( @@ -2870,6 +2901,54 @@ func testCustomChannelsLiquidityEdgeCasesCore(ctx context.Context, ) logBalance(t.t, nodes, assetID, "after safe asset htlc failure") + + // Another test case: Make sure an asset invoice contains the correct + // channel policy. We expect it to be the policy for the direction from + // edge node to receiver node. To test this, we first set two different + // policies on the channel between Erin and Fabia. + resp, err := erin.UpdateChannelPolicy(ctx, &lnrpc.PolicyUpdateRequest{ + Scope: &lnrpc.PolicyUpdateRequest_ChanPoint{ + ChanPoint: chanPointEF, + }, + BaseFeeMsat: 31337, + FeeRatePpm: 443322, + TimeLockDelta: 19, + }) + require.NoError(t.t, err) + require.Empty(t.t, resp.FailedUpdates) + + resp, err = fabia.UpdateChannelPolicy(ctx, &lnrpc.PolicyUpdateRequest{ + Scope: &lnrpc.PolicyUpdateRequest_ChanPoint{ + ChanPoint: chanPointEF, + }, + BaseFeeMsat: 42069, + FeeRatePpm: 223344, + TimeLockDelta: 18, + }) + require.NoError(t.t, err) + require.Empty(t.t, resp.FailedUpdates) + + // We now create an invoice on Fabia and expect Erin's policy to be used + // in the invoice. + invoiceResp = createAssetInvoice(t.t, erin, fabia, 1_000, assetID) + req, err := erin.DecodePayReq(ctx, &lnrpc.PayReqString{ + PayReq: invoiceResp.PaymentRequest, + }) + require.NoError(t.t, err) + + require.Len(t.t, req.RouteHints, 1) + require.Len(t.t, req.RouteHints[0].HopHints, 1) + invoiceHint := req.RouteHints[0].HopHints[0] + require.Equal(t.t, erin.PubKeyStr, invoiceHint.NodeId) + require.EqualValues(t.t, 31337, invoiceHint.FeeBaseMsat) + require.EqualValues(t.t, 443322, invoiceHint.FeeProportionalMillionths) + require.EqualValues(t.t, 19, invoiceHint.CltvExpiryDelta) + + // Now we pay the invoice and expect the same policy with very expensive + // fees to be used. + payInvoiceWithSatoshi( + t.t, dave, invoiceResp, withFeeLimit(100_000_000), + ) } // testCustomChannelsLiquidityEdgeCases is a test that runs through some diff --git a/litrpc/go.mod b/litrpc/go.mod index 3379f2e28..6eb4bd137 100644 --- a/litrpc/go.mod +++ b/litrpc/go.mod @@ -7,7 +7,7 @@ require ( github.com/lightninglabs/faraday/frdrpc v1.0.0 github.com/lightninglabs/loop/looprpc v1.0.0 github.com/lightninglabs/pool/poolrpc v1.0.0 - github.com/lightninglabs/taproot-assets/taprpc v1.0.5-0.20250526115916-1ac1deab2f9b + github.com/lightninglabs/taproot-assets/taprpc v1.0.7 github.com/lightningnetwork/lnd v0.19.0-beta google.golang.org/grpc v1.65.0 google.golang.org/protobuf v1.34.2 diff --git a/litrpc/go.sum b/litrpc/go.sum index 50616015e..4c06718cc 100644 --- a/litrpc/go.sum +++ b/litrpc/go.sum @@ -1102,8 +1102,8 @@ github.com/lightninglabs/pool/poolrpc v1.0.0 h1:vvosrgNx9WXF4mcHGqLjZOW8wNM0q+BL github.com/lightninglabs/pool/poolrpc v1.0.0/go.mod h1:ZqpEpBFRMMBAerMmilEjh27tqauSXDwLaLR0O3jvmMA= github.com/lightninglabs/protobuf-go-hex-display v1.34.2-hex-display h1:w7FM5LH9Z6CpKxl13mS48idsu6F+cEZf0lkyiV+Dq9g= github.com/lightninglabs/protobuf-go-hex-display v1.34.2-hex-display/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= -github.com/lightninglabs/taproot-assets/taprpc v1.0.5-0.20250526115916-1ac1deab2f9b h1:XmIJhYwUZ75BiZPXhsutwlgTin35QSjn+KhYbuPtHkQ= -github.com/lightninglabs/taproot-assets/taprpc v1.0.5-0.20250526115916-1ac1deab2f9b/go.mod h1:vOM2Ap2wYhEZjiJU7bNNg+e5tDxkvRAuyXwf/KQ4tgo= +github.com/lightninglabs/taproot-assets/taprpc v1.0.7 h1:yUG9vdpajiU0gp4wDkTPz/6BI8Vr52OM2paahlVrAys= +github.com/lightninglabs/taproot-assets/taprpc v1.0.7/go.mod h1:vOM2Ap2wYhEZjiJU7bNNg+e5tDxkvRAuyXwf/KQ4tgo= github.com/lightningnetwork/lightning-onion v1.2.1-0.20240712235311-98bd56499dfb h1:yfM05S8DXKhuCBp5qSMZdtSwvJ+GFzl94KbXMNB1JDY= github.com/lightningnetwork/lightning-onion v1.2.1-0.20240712235311-98bd56499dfb/go.mod h1:c0kvRShutpj3l6B9WtTsNTBUtjSmjZXbJd9ZBRQOSKI= github.com/lightningnetwork/lnd v0.19.0-beta h1:/8i2UdARiEpI2iAmPoSDcwZSSEuWqXyfsMxz/mLGbdw=