Skip to content

Commit 34e9e95

Browse files
committed
itest: add custom channels multi rfq receive itest
1 parent 3d9834d commit 34e9e95

File tree

2 files changed

+143
-0
lines changed

2 files changed

+143
-0
lines changed

itest/litd_custom_channels_test.go

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2892,6 +2892,144 @@ func testCustomChannelsLiquidityEdgeCasesGroup(ctx context.Context,
28922892
testCustomChannelsLiquidityEdgeCasesCore(ctx, net, t, true)
28932893
}
28942894

2895+
// testCustomChannelsMultiRFQReceive tests that a node creating an invoice with
2896+
// multiple RFQ quotes can actually guide the payer into using multiple private
2897+
// taproot asset channels to pay the invoice.
2898+
func testCustomChannelsMultiRFQReceive(ctx context.Context, net *NetworkHarness,
2899+
t *harnessTest) {
2900+
2901+
lndArgs := slices.Clone(lndArgsTemplate)
2902+
litdArgs := slices.Clone(litdArgsTemplate)
2903+
2904+
charlie, err := net.NewNode(
2905+
t.t, "Charlie", lndArgs, false, true, litdArgs...,
2906+
)
2907+
require.NoError(t.t, err)
2908+
2909+
litdArgs = append(litdArgs, fmt.Sprintf(
2910+
"--taproot-assets.proofcourieraddr=%s://%s",
2911+
proof.UniverseRpcCourierType, charlie.Cfg.LitAddr(),
2912+
))
2913+
2914+
dave, err := net.NewNode(t.t, "Dave", lndArgs, false, true, litdArgs...)
2915+
require.NoError(t.t, err)
2916+
erin, err := net.NewNode(t.t, "Erin", lndArgs, false, true, litdArgs...)
2917+
require.NoError(t.t, err)
2918+
fabia, err := net.NewNode(
2919+
t.t, "Fabia", lndArgs, false, true, litdArgs...,
2920+
)
2921+
require.NoError(t.t, err)
2922+
yara, err := net.NewNode(
2923+
t.t, "Yara", lndArgs, false, true, litdArgs...,
2924+
)
2925+
require.NoError(t.t, err)
2926+
2927+
nodes := []*HarnessNode{charlie, dave, erin, fabia, yara}
2928+
connectAllNodes(t.t, net, nodes)
2929+
fundAllNodes(t.t, net, nodes)
2930+
2931+
// Let's create the tap clients.
2932+
charlieTap := newTapClient(t.t, charlie)
2933+
daveTap := newTapClient(t.t, dave)
2934+
erinTap := newTapClient(t.t, erin)
2935+
fabiaTap := newTapClient(t.t, fabia)
2936+
yaraTap := newTapClient(t.t, yara)
2937+
2938+
assetReq := itest.CopyRequest(&mintrpc.MintAssetRequest{
2939+
Asset: itestAsset,
2940+
})
2941+
2942+
assetReq.Asset.NewGroupedAsset = true
2943+
2944+
// Mint an asset on Charlie and sync all nodes to Charlie as the
2945+
// universe.
2946+
mintedAssets := itest.MintAssetsConfirmBatch(
2947+
t.t, t.lndHarness.Miner.Client, charlieTap,
2948+
[]*mintrpc.MintAssetRequest{assetReq},
2949+
)
2950+
cents := mintedAssets[0]
2951+
assetID := cents.AssetGenesis.AssetId
2952+
groupID := cents.GetAssetGroup().GetTweakedGroupKey()
2953+
2954+
syncUniverses(t.t, charlieTap, dave, erin, fabia, yara)
2955+
2956+
multiRfqNodes := multiRfqNodes{
2957+
charlie: itestNode{
2958+
Lnd: charlie,
2959+
Tapd: charlieTap,
2960+
},
2961+
dave: itestNode{
2962+
Lnd: dave,
2963+
Tapd: daveTap,
2964+
},
2965+
erin: itestNode{
2966+
Lnd: erin,
2967+
Tapd: erinTap,
2968+
},
2969+
fabia: itestNode{
2970+
Lnd: fabia,
2971+
Tapd: fabiaTap,
2972+
},
2973+
yara: itestNode{
2974+
Lnd: yara,
2975+
Tapd: yaraTap,
2976+
},
2977+
universeTap: charlieTap,
2978+
}
2979+
2980+
createTestMultiRFQAssetNetwork(
2981+
t, net, multiRfqNodes, cents, 10_000, 10_000, 10_000,
2982+
)
2983+
2984+
logBalance(t.t, nodes, assetID, "before multi-rfq receive")
2985+
2986+
hodlInv := createAssetHodlInvoice(t.t, nil, fabia, 20_000, assetID)
2987+
2988+
payInvoiceWithSatoshi(
2989+
t.t, charlie, &lnrpc.AddInvoiceResponse{
2990+
PaymentRequest: hodlInv.payReq,
2991+
},
2992+
withGroupKey(groupID),
2993+
withFailure(lnrpc.Payment_IN_FLIGHT, failureNone),
2994+
)
2995+
2996+
logBalance(t.t, nodes, assetID, "after inflight multi-rfq")
2997+
2998+
// Assert that some HTLCs are present from Fabia's point of view.
2999+
assertMinNumHtlcs(t.t, fabia, 1)
3000+
3001+
// Assert that Charlie also has at least one outgoing HTLC as a sanity
3002+
// check.
3003+
assertMinNumHtlcs(t.t, charlie, 1)
3004+
3005+
// Now let's cancel the invoice and assert that all inbound channels
3006+
// have cleared their HTLCs.
3007+
payHash := hodlInv.preimage.Hash()
3008+
_, err = fabia.InvoicesClient.CancelInvoice(
3009+
ctx, &invoicesrpc.CancelInvoiceMsg{
3010+
PaymentHash: payHash[:],
3011+
},
3012+
)
3013+
require.NoError(t.t, err)
3014+
3015+
assertNumHtlcs(t.t, dave, 0)
3016+
assertNumHtlcs(t.t, erin, 0)
3017+
assertNumHtlcs(t.t, yara, 0)
3018+
3019+
logBalance(t.t, nodes, assetID, "after cancelled hodl")
3020+
3021+
// Now let's create a normal invoice that will be settled once all the
3022+
// HTLCs have been received. This is only possible because the payer
3023+
// uses multiple bolt11 hop hints to reach the destination.
3024+
invoiceResp := createAssetInvoice(t.t, nil, fabia, 15_000, assetID)
3025+
3026+
payInvoiceWithSatoshi(
3027+
t.t, charlie, invoiceResp, withGroupKey(groupID),
3028+
)
3029+
3030+
logBalance(t.t, nodes, assetID, "after multi-rfq receive")
3031+
}
3032+
28953033
// testCustomChannelsStrictForwarding is a test that tests the strict forwarding
28963034
// behavior of a node when it comes to paying asset invoices with assets and
28973035
// BTC invoices with satoshis.

itest/litd_test_list_on_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,4 +128,9 @@ var allTestCases = []*testCase{
128128
test: testCustomChannelsSelfPayment,
129129
noAliceBob: true,
130130
},
131+
{
132+
name: "custom channels multi rfq",
133+
test: testCustomChannelsMultiRFQReceive,
134+
noAliceBob: true,
135+
},
131136
}

0 commit comments

Comments
 (0)