Skip to content

Commit 7f5ae70

Browse files
committed
itest: test single sat keysend payment with no asset balance
Tests an edge case that previously lead to a force close due to the following error: unable to sort commitment transaction: output and allocation size mismatch with error Having a below-dust satoshi balance is only allowed when there is no asset balance. But since such a dust output isn't materialized on-chain, tapd needs to filter it out correctly and not create an allocation.
1 parent 8b87242 commit 7f5ae70

File tree

2 files changed

+54
-2
lines changed

2 files changed

+54
-2
lines changed

itest/assets_test.go

Lines changed: 22 additions & 1 deletion
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: 1_000_000,
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)
@@ -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: 32 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(

0 commit comments

Comments
 (0)