Skip to content

Commit

Permalink
itest: fix assertions, add new test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
guggero committed Dec 17, 2024
1 parent 4be9737 commit addaa56
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 16 deletions.
74 changes: 65 additions & 9 deletions itest/assets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -864,8 +864,8 @@ func payInvoiceWithSatoshi(t *testing.T, payer *HarnessNode,
require.NoError(t, err)

result, err := getPaymentResult(stream)
if cfg.expectTimeout {
require.ErrorContains(t, err, "context deadline exceeded")
if cfg.errSubStr != "" {
require.ErrorContains(t, err, cfg.errSubStr)
} else {
require.NoError(t, err)
require.Equal(t, cfg.payStatus, result.Status)
Expand Down Expand Up @@ -912,7 +912,9 @@ func payInvoiceWithSatoshiLastHop(t *testing.T, payer *HarnessNode,

type payConfig struct {
smallShards bool
expectTimeout bool
errSubStr string
allowOverpay bool
feeLimit lnwire.MilliSatoshi
payStatus lnrpc.Payment_PaymentStatus
failureReason lnrpc.PaymentFailureReason
rfq fn.Option[rfqmsg.ID]
Expand All @@ -921,7 +923,8 @@ type payConfig struct {
func defaultPayConfig() *payConfig {
return &payConfig{
smallShards: false,
expectTimeout: false,
errSubStr: "",
feeLimit: 1_000_000,
payStatus: lnrpc.Payment_SUCCEEDED,
failureReason: lnrpc.PaymentFailureReason_FAILURE_REASON_NONE,
}
Expand All @@ -935,9 +938,9 @@ func withSmallShards() payOpt {
}
}

func withExpectTimeout() payOpt {
func withPayErrSubStr(errSubStr string) payOpt {
return func(c *payConfig) {
c.expectTimeout = true
c.errSubStr = errSubStr
}
}

Expand All @@ -956,6 +959,18 @@ func withRFQ(rfqID rfqmsg.ID) payOpt {
}
}

func withFeeLimit(limit lnwire.MilliSatoshi) payOpt {
return func(c *payConfig) {
c.feeLimit = limit
}
}

func withAllowOverpay() payOpt {
return func(c *payConfig) {
c.allowOverpay = true
}
}

func payInvoiceWithAssets(t *testing.T, payer, rfqPeer *HarnessNode,
payReq string, assetID []byte,
opts ...payOpt) (uint64, rfqmath.BigIntFixedPoint) {
Expand All @@ -979,7 +994,7 @@ func payInvoiceWithAssets(t *testing.T, payer, rfqPeer *HarnessNode,
sendReq := &routerrpc.SendPaymentRequest{
PaymentRequest: payReq,
TimeoutSeconds: int32(PaymentTimeout.Seconds()),
FeeLimitMsat: 1_000_000,
FeeLimitMsat: int64(cfg.feeLimit),
}

if cfg.smallShards {
Expand All @@ -997,9 +1012,20 @@ func payInvoiceWithAssets(t *testing.T, payer, rfqPeer *HarnessNode,
PeerPubkey: rfqPeer.PubKey[:],
PaymentRequest: sendReq,
RfqId: rfqBytes,
AllowOverpay: cfg.allowOverpay,
})
require.NoError(t, err)

// 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.
if cfg.errSubStr != "" {
_, err := stream.Recv()
require.ErrorContains(t, err, cfg.errSubStr)

return 0, rfqmath.BigIntFixedPoint{}
}

var (
numUnits uint64
rateVal rfqmath.FixedPoint[rfqmath.BigInt]
Expand Down Expand Up @@ -1043,8 +1069,32 @@ func payInvoiceWithAssets(t *testing.T, payer, rfqPeer *HarnessNode,
return numUnits, rateVal
}

type invoiceConfig struct {
errSubStr string
}

func defaultInvoiceConfig() *invoiceConfig {
return &invoiceConfig{
errSubStr: "",
}
}

type invoiceOpt func(*invoiceConfig)

func withInvoiceErrSubStr(errSubStr string) invoiceOpt {
return func(c *invoiceConfig) {
c.errSubStr = errSubStr
}
}

func createAssetInvoice(t *testing.T, dstRfqPeer, dst *HarnessNode,
assetAmount uint64, assetID []byte) *lnrpc.AddInvoiceResponse {
assetAmount uint64, assetID []byte,
opts ...invoiceOpt) *lnrpc.AddInvoiceResponse {

cfg := defaultInvoiceConfig()
for _, opt := range opts {
opt(cfg)
}

ctxb := context.Background()
ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout)
Expand All @@ -1068,7 +1118,13 @@ func createAssetInvoice(t *testing.T, dstRfqPeer, dst *HarnessNode,
Expiry: timeoutSeconds,
},
})
require.NoError(t, err)
if cfg.errSubStr != "" {
require.ErrorContains(t, err, cfg.errSubStr)

return nil
} else {
require.NoError(t, err)
}

decodedInvoice, err := dst.DecodePayReq(ctxt, &lnrpc.PayReqString{
PayReq: resp.InvoiceResult.PaymentRequest,
Expand Down
54 changes: 47 additions & 7 deletions itest/litd_custom_channels_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import (
"github.com/lightninglabs/taproot-assets/proof"
"github.com/lightninglabs/taproot-assets/rfqmath"
"github.com/lightninglabs/taproot-assets/rfqmsg"
"github.com/lightninglabs/taproot-assets/tapchannel"
"github.com/lightninglabs/taproot-assets/taprpc"
"github.com/lightninglabs/taproot-assets/taprpc/mintrpc"
oraclerpc "github.com/lightninglabs/taproot-assets/taprpc/priceoraclerpc"
Expand Down Expand Up @@ -1983,20 +1982,61 @@ func testCustomChannelsLiquidityEdgeCases(ctxb context.Context,
// Yara with satoshi. This is a multi-hop payment going over 2 asset
// channels, where the total asset value is less than the default anchor
// amount of 354 sats.
invoiceResp = createAssetInvoice(t.t, dave, charlie, 1, assetID)
payInvoiceWithSatoshi(t.t, yara, invoiceResp, withFailure(
lnrpc.Payment_FAILED, failureNoRoute,
createAssetInvoice(t.t, dave, charlie, 1, assetID, withInvoiceErrSubStr(
"cannot create invoice over 1 asset units, as the minimal "+
"transportable amount",
))

logBalance(t.t, nodes, assetID, "after small payment (asset "+
"invoice, <354sats)")

// Edge case: We now create a small BTC invoice on Erin and ask Charlie
// to pay it with assets. We should get a payment failure as the amount
// is too small to be paid with assets economically. But a payment is
// still possible, since the amount is large enough to represent a
// single unit (17.1 sat per unit).
btcInvoiceResp, err := erin.AddInvoice(ctxb, &lnrpc.Invoice{
Memo: "small BTC invoice",
ValueMsat: 18_000,
})
require.NoError(t.t, err)
payInvoiceWithAssets(
t.t, charlie, dave, btcInvoiceResp.PaymentRequest, assetID,
withFeeLimit(2_000), withPayErrSubStr(
"rejecting payment of 20000 mSAT",
),
)

// When we override the uneconomical payment, it should succeed.
payInvoiceWithAssets(
t.t, charlie, dave, btcInvoiceResp.PaymentRequest, assetID,
withFeeLimit(2_000), withAllowOverpay(),
)
logBalance(
t.t, nodes, assetID, "after small payment (BTC invoice 1 sat)",
)

// When we try to pay an invoice amount that's smaller than the
// corresponding value of a single asset unit, the payment will always
// be rejected, even if we set the allow_uneconomical flag.
btcInvoiceResp, err = erin.AddInvoice(ctxb, &lnrpc.Invoice{
Memo: "very small BTC invoice",
ValueMsat: 1_000,
})
require.NoError(t.t, err)
payInvoiceWithAssets(
t.t, charlie, dave, btcInvoiceResp.PaymentRequest, assetID,
withFeeLimit(1_000), withAllowOverpay(), withPayErrSubStr(
"rejecting payment of 2000 mSAT",
),
)

// Edge case: Now Dave creates an asset invoice to be paid for by
// Yara with satoshi. For the last hop we try to settle the invoice in
// satoshi, where we will check whether Dave's strict forwarding works
// as expected. Charlie is only used as a dummy RFQ peer in this case,
// Yara totally ignored the RFQ hint and pays agnostically with sats.
invoiceResp = createAssetInvoice(t.t, charlie, dave, 1, assetID)
invoiceResp = createAssetInvoice(t.t, charlie, dave, 22, assetID)

stream, err := dave.InvoicesClient.SubscribeSingleInvoice(
ctxb, &invoicesrpc.SubscribeSingleInvoiceRequest{
Expand Down Expand Up @@ -2149,7 +2189,7 @@ func testCustomChannelsLiquidityEdgeCases(ctxb context.Context,
// Now Erin tries to pay the invoice. Since rfq quote cannot satisfy the
// total amount of the invoice this payment will fail.
payInvoiceWithSatoshi(
t.t, erin, iResp, withExpectTimeout(),
t.t, erin, iResp, withPayErrSubStr("context deadline exceeded"),
withFailure(lnrpc.Payment_FAILED, failureNone),
)

Expand Down Expand Up @@ -2702,7 +2742,7 @@ func testCustomChannelsOraclePricing(_ context.Context,
commitFeeP2WSH int64 = 2810
anchorAmount int64 = 330
assetHtlcCarryAmount = int64(
tapchannel.DefaultOnChainHtlcAmount,
rfqmath.DefaultOnChainHtlcSat,
)
unbalancedLocalAmount = channelFundingAmount - commitFeeP2TR -
anchorAmount
Expand Down

0 comments on commit addaa56

Please sign in to comment.