Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 17 additions & 10 deletions itest/assets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1423,13 +1423,15 @@ func sendAssetKeySendPayment(t *testing.T, src, dst *HarnessNode, amt uint64,
return
}

result, _, err := getAssetPaymentResult(t, stream, false)
tapPayment, err := getAssetPaymentResult(t, stream, false)
require.NoError(t, err)
if result.Status == lnrpc.Payment_FAILED {
t.Logf("Failure reason: %v", result.FailureReason)

payment := tapPayment.lndPayment
if payment.Status == lnrpc.Payment_FAILED {
t.Logf("Failure reason: %v", payment.FailureReason)
}
require.Equal(t, cfg.payStatus, result.Status)
require.Equal(t, cfg.failureReason, result.FailureReason)
require.Equal(t, cfg.payStatus, payment.Status)
require.Equal(t, cfg.failureReason, payment.FailureReason)
}

func sendKeySendPayment(t *testing.T, src, dst *HarnessNode,
Expand Down Expand Up @@ -1755,12 +1757,13 @@ func payInvoiceWithAssets(t *testing.T, payer, rfqPeer *HarnessNode,
sendReq.MaxShardSizeMsat = 80_000_000
}

var rfqBytes, peerPubKey []byte
var rfqBytes []byte
cfg.rfq.WhenSome(func(i rfqmsg.ID) {
rfqBytes = make([]byte, len(i[:]))
copy(rfqBytes, i[:])
})

var peerPubKey []byte
if rfqPeer != nil {
peerPubKey = rfqPeer.PubKey[:]
}
Expand All @@ -1785,7 +1788,7 @@ func payInvoiceWithAssets(t *testing.T, payer, rfqPeer *HarnessNode,

// If an error is returned by the RPC method (meaning the stream itself
// was established, no network or auth error), we expect the error to be
// returned on the first read on the stream.
// returned on the stream.
if cfg.errSubStr != "" {
msg, err := stream.Recv()

Expand All @@ -1804,14 +1807,18 @@ func payInvoiceWithAssets(t *testing.T, payer, rfqPeer *HarnessNode,
rateVal rfqmath.FixedPoint[rfqmath.BigInt]
)

result, rateVal, err := getAssetPaymentResult(
tapPayment, err := getAssetPaymentResult(
t, stream, cfg.payStatus == lnrpc.Payment_IN_FLIGHT,
)
require.NoError(t, err)
require.Equal(t, cfg.payStatus, result.Status)
require.Equal(t, cfg.failureReason, result.FailureReason)

payment := tapPayment.lndPayment
require.Equal(t, cfg.payStatus, payment.Status)
require.Equal(t, cfg.failureReason, payment.FailureReason)

amountMsat := lnwire.MilliSatoshi(decodedInvoice.NumMsat)

rateVal = tapPayment.assetRate
milliSatsFP := rfqmath.MilliSatoshiToUnits(amountMsat, rateVal)
numUnits = milliSatsFP.ScaleTo(0).ToUint64()

Expand Down
30 changes: 23 additions & 7 deletions itest/litd_accounts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -445,10 +445,21 @@ func getPaymentResult(stream routerrpc.Router_SendPaymentV2Client,
}
}

// TapPayment encapsulates all the information related to the outcome of a tap
// asset payment. It contains the outcome of the LND payment and also the asset
// rate that was used to swap the assets to satoshis.
type TapPayment struct {
// lndPayment contains the lnd part of the payment result.
lndPayment *lnrpc.Payment

// assetRate contains the asset rate that was used to convert the assets
// to sats.
assetRate rfqmath.FixedPoint[rfqmath.BigInt]
}

func getAssetPaymentResult(t *testing.T,
s tapchannelrpc.TaprootAssetChannels_SendPaymentClient,
isHodl bool) (*lnrpc.Payment, rfqmath.FixedPoint[rfqmath.BigInt],
error) {
isHodl bool) (*TapPayment, error) {

// No idea why it makes a difference whether we wait before calling
// s.Recv() or not, but it does. Without the sleep, the test will fail
Expand All @@ -461,7 +472,7 @@ func getAssetPaymentResult(t *testing.T,
for {
msg, err := s.Recv()
if err != nil {
return nil, rateVal, err
return nil, err
}

// Ignore RFQ quote acceptance messages read from the send
Expand Down Expand Up @@ -501,19 +512,24 @@ func getAssetPaymentResult(t *testing.T,

payment := msg.GetPaymentResult()
if payment == nil {
return nil, rateVal,
fmt.Errorf("unexpected message: %v", msg)
err := fmt.Errorf("unexpected message: %v", msg)
return nil, err
}

result := &TapPayment{
lndPayment: payment,
assetRate: rateVal,
}

// If this is a hodl payment, then we'll return the first
// expected response. Otherwise, we'll wait until the in flight
// clears to we can observe the other payment states.
switch {
case isHodl:
return payment, rateVal, nil
return result, nil

case payment.Status != lnrpc.Payment_IN_FLIGHT:
return payment, rateVal, nil
return result, nil
}
}
}
36 changes: 36 additions & 0 deletions itest/litd_custom_channels_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2959,6 +2959,42 @@ func testCustomChannelsLiquidityEdgeCasesCore(ctx context.Context,
payInvoiceWithSatoshi(
t.t, dave, invoiceResp, withFeeLimit(100_000_000),
)

logBalance(t.t, nodes, assetID, "after policy checks")

resBuy, err := daveTap.RfqClient.AddAssetBuyOrder(
ctx, &rfqrpc.AddAssetBuyOrderRequest{
AssetSpecifier: &assetSpecifier,
AssetMaxAmt: 1_000,
Expiry: uint64(inOneHour.Unix()),
PeerPubKey: charlie.PubKey[:],
TimeoutSeconds: 100,
},
)
require.NoError(t.t, err)

scid := resBuy.GetAcceptedQuote().Scid

invResp := createAssetInvoice(
t.t, charlie, dave, 1_000, assetID,
withInvGroupKey(groupID), withRouteHints([]*lnrpc.RouteHint{
{
HopHints: []*lnrpc.HopHint{
{
NodeId: charlie.PubKeyStr,
ChanId: scid,
},
},
},
}),
)

payInvoiceWithAssets(
t.t, charlie, dave, invResp.PaymentRequest, assetID,
withGroupKey(groupID),
)

logBalance(t.t, nodes, assetID, "after invoice with route hints")
}

// testCustomChannelsLiquidityEdgeCases is a test that runs through some
Expand Down
Loading