github.com/decred/dcrlnd@v0.7.6/channeldb/migration12/migration_test.go (about)

     1  package migration12_test
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"testing"
     7  
     8  	"github.com/decred/dcrlnd/channeldb/migration12"
     9  	"github.com/decred/dcrlnd/channeldb/migtest"
    10  	"github.com/decred/dcrlnd/kvdb"
    11  	"github.com/decred/dcrlnd/lntypes"
    12  )
    13  
    14  var (
    15  	// invoiceBucket is the name of the bucket within the database that
    16  	// stores all data related to invoices no matter their final state.
    17  	// Within the invoice bucket, each invoice is keyed by its invoice ID
    18  	// which is a monotonically increasing uint32.
    19  	invoiceBucket = []byte("invoices")
    20  
    21  	preimage = lntypes.Preimage{
    22  		0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
    23  		0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
    24  		0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
    25  		0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
    26  	}
    27  
    28  	hash = preimage.Hash()
    29  
    30  	beforeInvoice0Htlcs = []byte{
    31  		0x0b, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72,
    32  		0x6c, 0x64, 0x09, 0x62, 0x79, 0x65, 0x20, 0x77, 0x6f, 0x72,
    33  		0x6c, 0x64, 0x06, 0x70, 0x61, 0x79, 0x72, 0x65, 0x71, 0x00,
    34  		0x00, 0x00, 0x20, 0x00, 0x00, 0x4e, 0x94, 0x91, 0x4f, 0x00,
    35  		0x00, 0x0f, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x77, 0xc4, 0xd3,
    36  		0xd5, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x20, 0x0f, 0x01, 0x00,
    37  		0x00, 0x00, 0x0e, 0x77, 0xd5, 0xc8, 0x1c, 0x00, 0x00, 0x00,
    38  		0x00, 0xfe, 0x20, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
    39  		0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
    40  		0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
    41  		0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00,
    42  		0x00, 0x03, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    43  		0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
    44  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xa4,
    45  	}
    46  
    47  	afterInvoice0Htlcs = []byte{
    48  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x00, 0x0b,
    49  		0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c,
    50  		0x64, 0x01, 0x06, 0x70, 0x61, 0x79, 0x72, 0x65, 0x71, 0x02,
    51  		0x0f, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x77, 0xc4, 0xd3, 0xd5,
    52  		0x00, 0x00, 0x00, 0x00, 0xfe, 0x20, 0x03, 0x0f, 0x01, 0x00,
    53  		0x00, 0x00, 0x0e, 0x77, 0xd5, 0xc8, 0x1c, 0x00, 0x00, 0x00,
    54  		0x00, 0xfe, 0x20, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
    55  		0x00, 0x00, 0x05, 0x05, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
    56  		0x00, 0x00, 0x06, 0x06, 0x20, 0x42, 0x42, 0x42, 0x42, 0x42,
    57  		0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
    58  		0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
    59  		0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x07, 0x08, 0x00,
    60  		0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe8, 0x08, 0x04, 0x00,
    61  		0x00, 0x00, 0x20, 0x09, 0x08, 0x00, 0x00, 0x4e, 0x94, 0x91,
    62  		0x4f, 0x00, 0x00, 0x0a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
    63  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    64  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    65  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x0c,
    66  		0x01, 0x03, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    67  		0x01, 0xa4,
    68  	}
    69  
    70  	testHtlc = []byte{
    71  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
    72  		0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
    73  		0x03, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09,
    74  		0x05, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64,
    75  		0x07, 0x04, 0x00, 0x00, 0x00, 0x58, 0x09, 0x08, 0x00, 0x13,
    76  		0xbc, 0xbf, 0x72, 0x4e, 0x1e, 0x00, 0x0b, 0x08, 0x00, 0x17,
    77  		0xaf, 0x4c, 0x22, 0xc4, 0x24, 0x00, 0x0d, 0x04, 0x00, 0x00,
    78  		0x23, 0x1d, 0x0f, 0x01, 0x02,
    79  	}
    80  
    81  	beforeInvoice1Htlc = append([]byte{
    82  		0x0b, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72,
    83  		0x6c, 0x64, 0x09, 0x62, 0x79, 0x65, 0x20, 0x77, 0x6f, 0x72,
    84  		0x6c, 0x64, 0x06, 0x70, 0x61, 0x79, 0x72, 0x65, 0x71, 0x00,
    85  		0x00, 0x00, 0x20, 0x00, 0x00, 0x4e, 0x94, 0x91, 0x4f, 0x00,
    86  		0x00, 0x0f, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x77, 0xc4, 0xd3,
    87  		0xd5, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x20, 0x0f, 0x01, 0x00,
    88  		0x00, 0x00, 0x0e, 0x77, 0xd5, 0xc8, 0x1c, 0x00, 0x00, 0x00,
    89  		0x00, 0xfe, 0x20, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
    90  		0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
    91  		0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
    92  		0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00,
    93  		0x00, 0x03, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    94  		0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
    95  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xa4,
    96  	}, testHtlc...)
    97  
    98  	afterInvoice1Htlc = append([]byte{
    99  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x00, 0x0b,
   100  		0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c,
   101  		0x64, 0x01, 0x06, 0x70, 0x61, 0x79, 0x72, 0x65, 0x71, 0x02,
   102  		0x0f, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x77, 0xc4, 0xd3, 0xd5,
   103  		0x00, 0x00, 0x00, 0x00, 0xfe, 0x20, 0x03, 0x0f, 0x01, 0x00,
   104  		0x00, 0x00, 0x0e, 0x77, 0xd5, 0xc8, 0x1c, 0x00, 0x00, 0x00,
   105  		0x00, 0xfe, 0x20, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
   106  		0x00, 0x00, 0x05, 0x05, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
   107  		0x00, 0x00, 0x06, 0x06, 0x20, 0x42, 0x42, 0x42, 0x42, 0x42,
   108  		0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
   109  		0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
   110  		0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x07, 0x08, 0x00,
   111  		0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe8, 0x08, 0x04, 0x00,
   112  		0x00, 0x00, 0x20, 0x09, 0x08, 0x00, 0x00, 0x4e, 0x94, 0x91,
   113  		0x4f, 0x00, 0x00, 0x0a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
   114  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   115  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   116  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x0c,
   117  		0x01, 0x03, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   118  		0x01, 0xa4,
   119  	}, testHtlc...)
   120  )
   121  
   122  type migrationTest struct {
   123  	name            string
   124  	beforeMigration func(kvdb.RwTx) error
   125  	afterMigration  func(kvdb.RwTx) error
   126  }
   127  
   128  var migrationTests = []migrationTest{
   129  	{
   130  		name:            "no invoices",
   131  		beforeMigration: func(kvdb.RwTx) error { return nil },
   132  		afterMigration:  func(kvdb.RwTx) error { return nil },
   133  	},
   134  	{
   135  		name:            "zero htlcs",
   136  		beforeMigration: genBeforeMigration(beforeInvoice0Htlcs),
   137  		afterMigration:  genAfterMigration(afterInvoice0Htlcs),
   138  	},
   139  	{
   140  		name:            "one htlc",
   141  		beforeMigration: genBeforeMigration(beforeInvoice1Htlc),
   142  		afterMigration:  genAfterMigration(afterInvoice1Htlc),
   143  	},
   144  }
   145  
   146  // genBeforeMigration creates a closure that inserts an invoice serialized under
   147  // the old format under the test payment hash.
   148  func genBeforeMigration(beforeBytes []byte) func(kvdb.RwTx) error {
   149  	return func(tx kvdb.RwTx) error {
   150  		invoices, err := tx.CreateTopLevelBucket(
   151  			invoiceBucket,
   152  		)
   153  		if err != nil {
   154  			return err
   155  		}
   156  
   157  		return invoices.Put(hash[:], beforeBytes)
   158  	}
   159  }
   160  
   161  // genAfterMigration creates a closure that verifies the tlv invoice migration
   162  // succeeded, but comparing the resulting encoding of the invoice to the
   163  // expected serialization. In addition, the decoded invoice is compared against
   164  // the expected invoice for equality.
   165  func genAfterMigration(afterBytes []byte) func(kvdb.RwTx) error {
   166  	return func(tx kvdb.RwTx) error {
   167  		invoices := tx.ReadWriteBucket(invoiceBucket)
   168  		if invoices == nil {
   169  			return fmt.Errorf("invoice bucket not found")
   170  		}
   171  
   172  		// Fetch the new invoice bytes and check that they match our
   173  		// expected serialization.
   174  		invoiceBytes := invoices.Get(hash[:])
   175  		if !bytes.Equal(invoiceBytes, afterBytes) {
   176  			return fmt.Errorf("invoice bytes mismatch, "+
   177  				"want: %x, got: %x",
   178  				invoiceBytes, afterBytes)
   179  		}
   180  
   181  		return nil
   182  	}
   183  }
   184  
   185  // TestTLVInvoiceMigration executes a suite of migration tests for moving
   186  // invoices to use TLV for their bodies. In the process, feature bits and
   187  // payment addresses are added to the invoice while the receipt field is
   188  // dropped. We test a few different invoices with a varying number of HTLCs, as
   189  // well as the case where there are no invoices present.
   190  //
   191  // NOTE: The test vectors each include a receipt that is not present on the
   192  // final struct, but verifies that the field is properly removed.
   193  func TestTLVInvoiceMigration(t *testing.T) {
   194  	for _, test := range migrationTests {
   195  		test := test
   196  		t.Run(test.name, func(t *testing.T) {
   197  			migtest.ApplyMigration(
   198  				t,
   199  				test.beforeMigration,
   200  				test.afterMigration,
   201  				migration12.MigrateInvoiceTLV,
   202  				false,
   203  			)
   204  		})
   205  	}
   206  }