channeldb: update TestQueryPayments to cover duplicate payments
Update our current tests to include lookup of duplicate payments. We do so in preparation for changing our lookup to be based on a new payments index. We add an append duplicate function which will add a duplicate payment with the minimum information required to successfully read it from disk in tests.
This commit is contained in:
parent
38b8e54ba7
commit
6c4a1f4f99
@ -9,11 +9,13 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec"
|
||||
"github.com/btcsuite/btcwallet/walletdb"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/lightningnetwork/lnd/channeldb/kvdb"
|
||||
"github.com/lightningnetwork/lnd/lntypes"
|
||||
"github.com/lightningnetwork/lnd/record"
|
||||
"github.com/lightningnetwork/lnd/routing/route"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -188,6 +190,10 @@ func deletePayment(t *testing.T, db *DB, paymentHash lntypes.Hash) {
|
||||
func TestQueryPayments(t *testing.T) {
|
||||
// Define table driven test for QueryPayments.
|
||||
// Test payments have sequence indices [1, 3, 4, 5, 6, 7].
|
||||
// Note that the payment with index 7 has the same payment hash as 6,
|
||||
// and is stored in a nested bucket within payment 6 rather than being
|
||||
// its own entry in the payments bucket. We do this to test retrieval
|
||||
// of legacy payments.
|
||||
tests := []struct {
|
||||
name string
|
||||
query PaymentsQuery
|
||||
@ -359,10 +365,16 @@ func TestQueryPayments(t *testing.T) {
|
||||
}
|
||||
|
||||
// Populate the database with a set of test payments.
|
||||
numberOfPayments := 7
|
||||
// We create 6 original payments, deleting the payment
|
||||
// at index 2 so that we cover the case where sequence
|
||||
// numbers are missing. We also add a duplicate payment
|
||||
// to the last payment added to test the legacy case
|
||||
// where we have duplicates in the nested duplicates
|
||||
// bucket.
|
||||
nonDuplicatePayments := 6
|
||||
pControl := NewPaymentControl(db)
|
||||
|
||||
for i := 0; i < numberOfPayments; i++ {
|
||||
for i := 0; i < nonDuplicatePayments; i++ {
|
||||
// Generate a test payment.
|
||||
info, _, _, err := genInfo()
|
||||
if err != nil {
|
||||
@ -381,6 +393,22 @@ func TestQueryPayments(t *testing.T) {
|
||||
if i == 1 {
|
||||
deletePayment(t, db, info.PaymentHash)
|
||||
}
|
||||
|
||||
// If we are on the last payment entry, add a
|
||||
// duplicate payment with sequence number equal
|
||||
// to the parent payment + 1.
|
||||
if i == (nonDuplicatePayments - 1) {
|
||||
pmt, err := pControl.FetchPayment(
|
||||
info.PaymentHash,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
appendDuplicatePayment(
|
||||
t, pControl.db,
|
||||
info.PaymentHash,
|
||||
pmt.SequenceNum+1,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch all payments in the database.
|
||||
@ -424,3 +452,83 @@ func TestQueryPayments(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// appendDuplicatePayment adds a duplicate payment to an existing payment. Note
|
||||
// that this function requires a unique sequence number.
|
||||
//
|
||||
// This code is *only* intended to replicate legacy duplicate payments in lnd,
|
||||
// our current schema does not allow duplicates.
|
||||
func appendDuplicatePayment(t *testing.T, db *DB, paymentHash lntypes.Hash,
|
||||
seqNr uint64) {
|
||||
|
||||
err := kvdb.Update(db, func(tx walletdb.ReadWriteTx) error {
|
||||
bucket, err := fetchPaymentBucketUpdate(
|
||||
tx, paymentHash,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create the duplicates bucket if it is not
|
||||
// present.
|
||||
dup, err := bucket.CreateBucketIfNotExists(
|
||||
duplicatePaymentsBucket,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var sequenceKey [8]byte
|
||||
byteOrder.PutUint64(sequenceKey[:], seqNr)
|
||||
|
||||
// Create duplicate payments for the two dup
|
||||
// sequence numbers we've setup.
|
||||
putDuplicatePayment(t, dup, sequenceKey[:], paymentHash)
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("could not create payment: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// putDuplicatePayment creates a duplicate payment in the duplicates bucket
|
||||
// provided with the minimal information required for successful reading.
|
||||
func putDuplicatePayment(t *testing.T, duplicateBucket kvdb.RwBucket,
|
||||
sequenceKey []byte, paymentHash lntypes.Hash) {
|
||||
|
||||
paymentBucket, err := duplicateBucket.CreateBucketIfNotExists(
|
||||
sequenceKey,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = paymentBucket.Put(duplicatePaymentSequenceKey, sequenceKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Generate fake information for the duplicate payment.
|
||||
info, _, _, err := genInfo()
|
||||
require.NoError(t, err)
|
||||
|
||||
// Write the payment info to disk under the creation info key. This code
|
||||
// is copied rather than using serializePaymentCreationInfo to ensure
|
||||
// we always write in the legacy format used by duplicate payments.
|
||||
var b bytes.Buffer
|
||||
var scratch [8]byte
|
||||
_, err = b.Write(paymentHash[:])
|
||||
require.NoError(t, err)
|
||||
|
||||
byteOrder.PutUint64(scratch[:], uint64(info.Value))
|
||||
_, err = b.Write(scratch[:])
|
||||
require.NoError(t, err)
|
||||
|
||||
err = serializeTime(&b, info.CreationTime)
|
||||
require.NoError(t, err)
|
||||
|
||||
byteOrder.PutUint32(scratch[:4], 0)
|
||||
_, err = b.Write(scratch[:4])
|
||||
require.NoError(t, err)
|
||||
|
||||
// Get the PaymentCreationInfo.
|
||||
err = paymentBucket.Put(duplicatePaymentCreationInfoKey, b.Bytes())
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user