mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-11-11 22:57:59 +01:00
invoices/test: add test context
This commit adds a test context for invoice registry and additionally passed in a payload object to NotifyExitHopHtlc. This makes the test match the reality better where a payload is always provided.
This commit is contained in:
@@ -9,6 +9,7 @@ import (
|
|||||||
"github.com/lightningnetwork/lnd/channeldb"
|
"github.com/lightningnetwork/lnd/channeldb"
|
||||||
"github.com/lightningnetwork/lnd/lntypes"
|
"github.com/lightningnetwork/lnd/lntypes"
|
||||||
"github.com/lightningnetwork/lnd/lnwire"
|
"github.com/lightningnetwork/lnd/lnwire"
|
||||||
|
"github.com/lightningnetwork/lnd/record"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -32,9 +33,12 @@ var (
|
|||||||
testFeatures = lnwire.NewFeatureVector(
|
testFeatures = lnwire.NewFeatureVector(
|
||||||
nil, lnwire.Features,
|
nil, lnwire.Features,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
testPayload = &mockPayload{}
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
testInvoiceAmt = lnwire.MilliSatoshi(100000)
|
||||||
testInvoice = &channeldb.Invoice{
|
testInvoice = &channeldb.Invoice{
|
||||||
Terms: channeldb.ContractTerm{
|
Terms: channeldb.ContractTerm{
|
||||||
PaymentPreimage: preimage,
|
PaymentPreimage: preimage,
|
||||||
@@ -46,19 +50,26 @@ var (
|
|||||||
testHodlInvoice = &channeldb.Invoice{
|
testHodlInvoice = &channeldb.Invoice{
|
||||||
Terms: channeldb.ContractTerm{
|
Terms: channeldb.ContractTerm{
|
||||||
PaymentPreimage: channeldb.UnknownPreimage,
|
PaymentPreimage: channeldb.UnknownPreimage,
|
||||||
Value: lnwire.MilliSatoshi(100000),
|
Value: testInvoiceAmt,
|
||||||
Features: testFeatures,
|
Features: testFeatures,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func newTestContext(t *testing.T) (*InvoiceRegistry, func()) {
|
type testContext struct {
|
||||||
|
registry *InvoiceRegistry
|
||||||
|
|
||||||
|
cleanup func()
|
||||||
|
t *testing.T
|
||||||
|
}
|
||||||
|
|
||||||
|
func newTestContext(t *testing.T) *testContext {
|
||||||
cdb, cleanup, err := newDB()
|
cdb, cleanup, err := newDB()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Instantiate and start the invoice registry.
|
// Instantiate and start the invoice ctx.registry.
|
||||||
registry := NewRegistry(cdb, testFinalCltvRejectDelta)
|
registry := NewRegistry(cdb, testFinalCltvRejectDelta)
|
||||||
|
|
||||||
err = registry.Start()
|
err = registry.Start()
|
||||||
@@ -67,10 +78,16 @@ func newTestContext(t *testing.T) (*InvoiceRegistry, func()) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return registry, func() {
|
ctx := testContext{
|
||||||
|
registry: registry,
|
||||||
|
t: t,
|
||||||
|
cleanup: func() {
|
||||||
registry.Stop()
|
registry.Stop()
|
||||||
cleanup()
|
cleanup()
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return &ctx
|
||||||
}
|
}
|
||||||
|
|
||||||
func getCircuitKey(htlcID uint64) channeldb.CircuitKey {
|
func getCircuitKey(htlcID uint64) channeldb.CircuitKey {
|
||||||
@@ -84,14 +101,14 @@ func getCircuitKey(htlcID uint64) channeldb.CircuitKey {
|
|||||||
|
|
||||||
// TestSettleInvoice tests settling of an invoice and related notifications.
|
// TestSettleInvoice tests settling of an invoice and related notifications.
|
||||||
func TestSettleInvoice(t *testing.T) {
|
func TestSettleInvoice(t *testing.T) {
|
||||||
registry, cleanup := newTestContext(t)
|
ctx := newTestContext(t)
|
||||||
defer cleanup()
|
defer ctx.cleanup()
|
||||||
|
|
||||||
allSubscriptions := registry.SubscribeNotifications(0, 0)
|
allSubscriptions := ctx.registry.SubscribeNotifications(0, 0)
|
||||||
defer allSubscriptions.Cancel()
|
defer allSubscriptions.Cancel()
|
||||||
|
|
||||||
// Subscribe to the not yet existing invoice.
|
// Subscribe to the not yet existing invoice.
|
||||||
subscription, err := registry.SubscribeSingleInvoice(hash)
|
subscription, err := ctx.registry.SubscribeSingleInvoice(hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -102,7 +119,7 @@ func TestSettleInvoice(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add the invoice.
|
// Add the invoice.
|
||||||
addIdx, err := registry.AddInvoice(testInvoice, hash)
|
addIdx, err := ctx.registry.AddInvoice(testInvoice, hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -137,10 +154,10 @@ func TestSettleInvoice(t *testing.T) {
|
|||||||
hodlChan := make(chan interface{}, 1)
|
hodlChan := make(chan interface{}, 1)
|
||||||
|
|
||||||
// Try to settle invoice with an htlc that expires too soon.
|
// Try to settle invoice with an htlc that expires too soon.
|
||||||
event, err := registry.NotifyExitHopHtlc(
|
event, err := ctx.registry.NotifyExitHopHtlc(
|
||||||
hash, testInvoice.Terms.Value,
|
hash, testInvoice.Terms.Value,
|
||||||
uint32(testCurrentHeight)+testInvoiceCltvDelta-1,
|
uint32(testCurrentHeight)+testInvoiceCltvDelta-1,
|
||||||
testCurrentHeight, getCircuitKey(10), hodlChan, nil,
|
testCurrentHeight, getCircuitKey(10), hodlChan, testPayload,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -155,9 +172,9 @@ func TestSettleInvoice(t *testing.T) {
|
|||||||
|
|
||||||
// Settle invoice with a slightly higher amount.
|
// Settle invoice with a slightly higher amount.
|
||||||
amtPaid := lnwire.MilliSatoshi(100500)
|
amtPaid := lnwire.MilliSatoshi(100500)
|
||||||
_, err = registry.NotifyExitHopHtlc(
|
_, err = ctx.registry.NotifyExitHopHtlc(
|
||||||
hash, amtPaid, testHtlcExpiry, testCurrentHeight,
|
hash, amtPaid, testHtlcExpiry, testCurrentHeight,
|
||||||
getCircuitKey(0), hodlChan, nil,
|
getCircuitKey(0), hodlChan, testPayload,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -191,9 +208,9 @@ func TestSettleInvoice(t *testing.T) {
|
|||||||
|
|
||||||
// Try to settle again with the same htlc id. We need this idempotent
|
// Try to settle again with the same htlc id. We need this idempotent
|
||||||
// behaviour after a restart.
|
// behaviour after a restart.
|
||||||
event, err = registry.NotifyExitHopHtlc(
|
event, err = ctx.registry.NotifyExitHopHtlc(
|
||||||
hash, amtPaid, testHtlcExpiry, testCurrentHeight,
|
hash, amtPaid, testHtlcExpiry, testCurrentHeight,
|
||||||
getCircuitKey(0), hodlChan, nil,
|
getCircuitKey(0), hodlChan, testPayload,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected NotifyExitHopHtlc error: %v", err)
|
t.Fatalf("unexpected NotifyExitHopHtlc error: %v", err)
|
||||||
@@ -205,9 +222,9 @@ func TestSettleInvoice(t *testing.T) {
|
|||||||
// Try to settle again with a new higher-valued htlc. This payment
|
// Try to settle again with a new higher-valued htlc. This payment
|
||||||
// should also be accepted, to prevent any change in behaviour for a
|
// should also be accepted, to prevent any change in behaviour for a
|
||||||
// paid invoice that may open up a probe vector.
|
// paid invoice that may open up a probe vector.
|
||||||
event, err = registry.NotifyExitHopHtlc(
|
event, err = ctx.registry.NotifyExitHopHtlc(
|
||||||
hash, amtPaid+600, testHtlcExpiry, testCurrentHeight,
|
hash, amtPaid+600, testHtlcExpiry, testCurrentHeight,
|
||||||
getCircuitKey(1), hodlChan, nil,
|
getCircuitKey(1), hodlChan, testPayload,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected NotifyExitHopHtlc error: %v", err)
|
t.Fatalf("unexpected NotifyExitHopHtlc error: %v", err)
|
||||||
@@ -218,9 +235,9 @@ func TestSettleInvoice(t *testing.T) {
|
|||||||
|
|
||||||
// Try to settle again with a lower amount. This should fail just as it
|
// Try to settle again with a lower amount. This should fail just as it
|
||||||
// would have failed if it were the first payment.
|
// would have failed if it were the first payment.
|
||||||
event, err = registry.NotifyExitHopHtlc(
|
event, err = ctx.registry.NotifyExitHopHtlc(
|
||||||
hash, amtPaid-600, testHtlcExpiry, testCurrentHeight,
|
hash, amtPaid-600, testHtlcExpiry, testCurrentHeight,
|
||||||
getCircuitKey(2), hodlChan, nil,
|
getCircuitKey(2), hodlChan, testPayload,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected NotifyExitHopHtlc error: %v", err)
|
t.Fatalf("unexpected NotifyExitHopHtlc error: %v", err)
|
||||||
@@ -231,7 +248,7 @@ func TestSettleInvoice(t *testing.T) {
|
|||||||
|
|
||||||
// Check that settled amount is equal to the sum of values of the htlcs
|
// Check that settled amount is equal to the sum of values of the htlcs
|
||||||
// 0 and 1.
|
// 0 and 1.
|
||||||
inv, err := registry.LookupInvoice(hash)
|
inv, err := ctx.registry.LookupInvoice(hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -240,7 +257,7 @@ func TestSettleInvoice(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Try to cancel.
|
// Try to cancel.
|
||||||
err = registry.CancelInvoice(hash)
|
err = ctx.registry.CancelInvoice(hash)
|
||||||
if err != channeldb.ErrInvoiceAlreadySettled {
|
if err != channeldb.ErrInvoiceAlreadySettled {
|
||||||
t.Fatal("expected cancelation of a settled invoice to fail")
|
t.Fatal("expected cancelation of a settled invoice to fail")
|
||||||
}
|
}
|
||||||
@@ -255,20 +272,20 @@ func TestSettleInvoice(t *testing.T) {
|
|||||||
|
|
||||||
// TestCancelInvoice tests cancelation of an invoice and related notifications.
|
// TestCancelInvoice tests cancelation of an invoice and related notifications.
|
||||||
func TestCancelInvoice(t *testing.T) {
|
func TestCancelInvoice(t *testing.T) {
|
||||||
registry, cleanup := newTestContext(t)
|
ctx := newTestContext(t)
|
||||||
defer cleanup()
|
defer ctx.cleanup()
|
||||||
|
|
||||||
allSubscriptions := registry.SubscribeNotifications(0, 0)
|
allSubscriptions := ctx.registry.SubscribeNotifications(0, 0)
|
||||||
defer allSubscriptions.Cancel()
|
defer allSubscriptions.Cancel()
|
||||||
|
|
||||||
// Try to cancel the not yet existing invoice. This should fail.
|
// Try to cancel the not yet existing invoice. This should fail.
|
||||||
err := registry.CancelInvoice(hash)
|
err := ctx.registry.CancelInvoice(hash)
|
||||||
if err != channeldb.ErrInvoiceNotFound {
|
if err != channeldb.ErrInvoiceNotFound {
|
||||||
t.Fatalf("expected ErrInvoiceNotFound, but got %v", err)
|
t.Fatalf("expected ErrInvoiceNotFound, but got %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Subscribe to the not yet existing invoice.
|
// Subscribe to the not yet existing invoice.
|
||||||
subscription, err := registry.SubscribeSingleInvoice(hash)
|
subscription, err := ctx.registry.SubscribeSingleInvoice(hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -280,7 +297,7 @@ func TestCancelInvoice(t *testing.T) {
|
|||||||
|
|
||||||
// Add the invoice.
|
// Add the invoice.
|
||||||
amt := lnwire.MilliSatoshi(100000)
|
amt := lnwire.MilliSatoshi(100000)
|
||||||
_, err = registry.AddInvoice(testInvoice, hash)
|
_, err = ctx.registry.AddInvoice(testInvoice, hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -312,7 +329,7 @@ func TestCancelInvoice(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Cancel invoice.
|
// Cancel invoice.
|
||||||
err = registry.CancelInvoice(hash)
|
err = ctx.registry.CancelInvoice(hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -335,7 +352,7 @@ func TestCancelInvoice(t *testing.T) {
|
|||||||
// subscribers (backwards compatibility).
|
// subscribers (backwards compatibility).
|
||||||
|
|
||||||
// Try to cancel again.
|
// Try to cancel again.
|
||||||
err = registry.CancelInvoice(hash)
|
err = ctx.registry.CancelInvoice(hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("expected cancelation of a canceled invoice to succeed")
|
t.Fatal("expected cancelation of a canceled invoice to succeed")
|
||||||
}
|
}
|
||||||
@@ -343,9 +360,9 @@ func TestCancelInvoice(t *testing.T) {
|
|||||||
// Notify arrival of a new htlc paying to this invoice. This should
|
// Notify arrival of a new htlc paying to this invoice. This should
|
||||||
// result in a cancel event.
|
// result in a cancel event.
|
||||||
hodlChan := make(chan interface{})
|
hodlChan := make(chan interface{})
|
||||||
event, err := registry.NotifyExitHopHtlc(
|
event, err := ctx.registry.NotifyExitHopHtlc(
|
||||||
hash, amt, testHtlcExpiry, testCurrentHeight,
|
hash, amt, testHtlcExpiry, testCurrentHeight,
|
||||||
getCircuitKey(0), hodlChan, nil,
|
getCircuitKey(0), hodlChan, testPayload,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("expected settlement of a canceled invoice to succeed")
|
t.Fatal("expected settlement of a canceled invoice to succeed")
|
||||||
@@ -371,7 +388,7 @@ func TestSettleHoldInvoice(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer cleanup()
|
defer cleanup()
|
||||||
|
|
||||||
// Instantiate and start the invoice registry.
|
// Instantiate and start the invoice ctx.registry.
|
||||||
registry := NewRegistry(cdb, testFinalCltvRejectDelta)
|
registry := NewRegistry(cdb, testFinalCltvRejectDelta)
|
||||||
|
|
||||||
err = registry.Start()
|
err = registry.Start()
|
||||||
@@ -423,7 +440,7 @@ func TestSettleHoldInvoice(t *testing.T) {
|
|||||||
// should be possible.
|
// should be possible.
|
||||||
event, err := registry.NotifyExitHopHtlc(
|
event, err := registry.NotifyExitHopHtlc(
|
||||||
hash, amtPaid, testHtlcExpiry, testCurrentHeight,
|
hash, amtPaid, testHtlcExpiry, testCurrentHeight,
|
||||||
getCircuitKey(0), hodlChan, nil,
|
getCircuitKey(0), hodlChan, testPayload,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("expected settle to succeed but got %v", err)
|
t.Fatalf("expected settle to succeed but got %v", err)
|
||||||
@@ -435,7 +452,7 @@ func TestSettleHoldInvoice(t *testing.T) {
|
|||||||
// Test idempotency.
|
// Test idempotency.
|
||||||
event, err = registry.NotifyExitHopHtlc(
|
event, err = registry.NotifyExitHopHtlc(
|
||||||
hash, amtPaid, testHtlcExpiry, testCurrentHeight,
|
hash, amtPaid, testHtlcExpiry, testCurrentHeight,
|
||||||
getCircuitKey(0), hodlChan, nil,
|
getCircuitKey(0), hodlChan, testPayload,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("expected settle to succeed but got %v", err)
|
t.Fatalf("expected settle to succeed but got %v", err)
|
||||||
@@ -448,7 +465,7 @@ func TestSettleHoldInvoice(t *testing.T) {
|
|||||||
// is a replay.
|
// is a replay.
|
||||||
event, err = registry.NotifyExitHopHtlc(
|
event, err = registry.NotifyExitHopHtlc(
|
||||||
hash, amtPaid, testHtlcExpiry, testCurrentHeight+10,
|
hash, amtPaid, testHtlcExpiry, testCurrentHeight+10,
|
||||||
getCircuitKey(0), hodlChan, nil,
|
getCircuitKey(0), hodlChan, testPayload,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("expected settle to succeed but got %v", err)
|
t.Fatalf("expected settle to succeed but got %v", err)
|
||||||
@@ -461,7 +478,7 @@ func TestSettleHoldInvoice(t *testing.T) {
|
|||||||
// requirement. It should be rejected.
|
// requirement. It should be rejected.
|
||||||
event, err = registry.NotifyExitHopHtlc(
|
event, err = registry.NotifyExitHopHtlc(
|
||||||
hash, amtPaid, 1, testCurrentHeight,
|
hash, amtPaid, 1, testCurrentHeight,
|
||||||
getCircuitKey(1), hodlChan, nil,
|
getCircuitKey(1), hodlChan, testPayload,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("expected settle to succeed but got %v", err)
|
t.Fatalf("expected settle to succeed but got %v", err)
|
||||||
@@ -539,7 +556,7 @@ func TestCancelHoldInvoice(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer cleanup()
|
defer cleanup()
|
||||||
|
|
||||||
// Instantiate and start the invoice registry.
|
// Instantiate and start the invoice ctx.registry.
|
||||||
registry := NewRegistry(cdb, testFinalCltvRejectDelta)
|
registry := NewRegistry(cdb, testFinalCltvRejectDelta)
|
||||||
|
|
||||||
err = registry.Start()
|
err = registry.Start()
|
||||||
@@ -561,7 +578,7 @@ func TestCancelHoldInvoice(t *testing.T) {
|
|||||||
// should be possible.
|
// should be possible.
|
||||||
event, err := registry.NotifyExitHopHtlc(
|
event, err := registry.NotifyExitHopHtlc(
|
||||||
hash, amtPaid, testHtlcExpiry, testCurrentHeight,
|
hash, amtPaid, testHtlcExpiry, testCurrentHeight,
|
||||||
getCircuitKey(0), hodlChan, nil,
|
getCircuitKey(0), hodlChan, testPayload,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("expected settle to succeed but got %v", err)
|
t.Fatalf("expected settle to succeed but got %v", err)
|
||||||
@@ -586,7 +603,7 @@ func TestCancelHoldInvoice(t *testing.T) {
|
|||||||
// accept height.
|
// accept height.
|
||||||
event, err = registry.NotifyExitHopHtlc(
|
event, err = registry.NotifyExitHopHtlc(
|
||||||
hash, amtPaid, testHtlcExpiry, testCurrentHeight+1,
|
hash, amtPaid, testHtlcExpiry, testCurrentHeight+1,
|
||||||
getCircuitKey(0), hodlChan, nil,
|
getCircuitKey(0), hodlChan, testPayload,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("expected settle to succeed but got %v", err)
|
t.Fatalf("expected settle to succeed but got %v", err)
|
||||||
@@ -629,18 +646,26 @@ func newDB() (*channeldb.DB, func(), error) {
|
|||||||
// the exit hop, but in htlcIncomingContestResolver it is called with forwarded
|
// the exit hop, but in htlcIncomingContestResolver it is called with forwarded
|
||||||
// htlc hashes as well.
|
// htlc hashes as well.
|
||||||
func TestUnknownInvoice(t *testing.T) {
|
func TestUnknownInvoice(t *testing.T) {
|
||||||
registry, cleanup := newTestContext(t)
|
ctx := newTestContext(t)
|
||||||
defer cleanup()
|
defer ctx.cleanup()
|
||||||
|
|
||||||
// Notify arrival of a new htlc paying to this invoice. This should
|
// Notify arrival of a new htlc paying to this invoice. This should
|
||||||
// succeed.
|
// succeed.
|
||||||
hodlChan := make(chan interface{})
|
hodlChan := make(chan interface{})
|
||||||
amt := lnwire.MilliSatoshi(100000)
|
amt := lnwire.MilliSatoshi(100000)
|
||||||
_, err := registry.NotifyExitHopHtlc(
|
_, err := ctx.registry.NotifyExitHopHtlc(
|
||||||
hash, amt, testHtlcExpiry, testCurrentHeight,
|
hash, amt, testHtlcExpiry, testCurrentHeight,
|
||||||
getCircuitKey(0), hodlChan, nil,
|
getCircuitKey(0), hodlChan, testPayload,
|
||||||
)
|
)
|
||||||
if err != channeldb.ErrInvoiceNotFound {
|
if err != channeldb.ErrInvoiceNotFound {
|
||||||
t.Fatal("expected invoice not found error")
|
t.Fatal("expected invoice not found error")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type mockPayload struct {
|
||||||
|
mpp *record.MPP
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *mockPayload) MultiPath() *record.MPP {
|
||||||
|
return p.mpp
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user