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

     1  package channeldb
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/decred/dcrlnd/kvdb"
     7  )
     8  
     9  // TestSaneNextKeyFamilyIndex tests that the generation of key family indices
    10  // is sane and follows the propper semantics.
    11  func TestSaneNextKeyFamilyIndex(t *testing.T) {
    12  	t.Parallel()
    13  
    14  	db, cleanUp, err := MakeTestDB()
    15  	defer cleanUp()
    16  	if err != nil {
    17  		t.Fatalf("unable to make test db: %v", err)
    18  	}
    19  
    20  	// Two consecutive calls should generate different indices for the same
    21  	// key family.
    22  	i1, err := db.NextKeyFamilyIndex(0)
    23  	if err != nil {
    24  		t.Fatalf("unable to generate first index: %v", err)
    25  	}
    26  
    27  	if i1 != 0 {
    28  		t.Fatalf("the first returned index should be 0")
    29  	}
    30  
    31  	i2, err := db.NextKeyFamilyIndex(0)
    32  	if err != nil {
    33  		t.Fatalf("unable to generate second index: %v", err)
    34  	}
    35  	if i2 != 1 {
    36  		t.Fatalf("the second returned index should be 1")
    37  	}
    38  
    39  	// Generating for a new key family should return the first index again.
    40  	i3, err := db.NextKeyFamilyIndex(1)
    41  	if err != nil {
    42  		t.Fatalf("unable to generate index for second family: %v", err)
    43  	}
    44  	if i3 != 0 {
    45  		t.Fatalf("the index for the second family should be 0")
    46  	}
    47  
    48  	// Trying to generate an index for an invalid family should return an
    49  	// error.
    50  	_, err = db.NextKeyFamilyIndex(0x80000000)
    51  	if err != errInvalidKeyFamily {
    52  		t.Fatalf("invalid family should return correct error; got %v",
    53  			err)
    54  	}
    55  
    56  	// Manually change the db to simulate exhausting a key family
    57  	err = kvdb.Update(db, func(tx kvdb.RwTx) error {
    58  		keychain, err := tx.CreateTopLevelBucket(keychainBucket)
    59  		if err != nil {
    60  			return err
    61  		}
    62  
    63  		keyFamilies, err := keychain.CreateBucketIfNotExists(
    64  			keyFamilyIndexesBucket,
    65  		)
    66  		if err != nil {
    67  			return err
    68  		}
    69  
    70  		// Write the maximum usable index to the keyFamily 0
    71  		var k [4]byte
    72  		var v [4]byte
    73  		byteOrder.PutUint32(v[:], 0x7fffffff)
    74  		keyFamilies.Put(k[:], v[:])
    75  		return nil
    76  	}, func() {})
    77  	if err != nil {
    78  		t.Fatalf("unable to manipulate db: %v", err)
    79  	}
    80  
    81  	// Try to generate the next index. It should fail.
    82  	_, err = db.NextKeyFamilyIndex(0)
    83  	if err != errKeyFamilyExhausted {
    84  		t.Fatalf("exhausted family should return correct error; got %v",
    85  			err)
    86  	}
    87  }
    88  
    89  // TestAtomicAccountID tests if the comparison of account IDs work as expected.
    90  func TestAtomicAccountID(t *testing.T) {
    91  	db, cleanUp, err := MakeTestDB()
    92  	defer cleanUp()
    93  	if err != nil {
    94  		t.Fatalf("unable to make test db: %v", err)
    95  	}
    96  
    97  	v := make([]byte, 32)
    98  	err = db.CompareAndStoreAccountID(v)
    99  	if err != nil {
   100  		t.Fatalf("expected first comparison to not error. got %v", err)
   101  	}
   102  
   103  	err = db.CompareAndStoreAccountID(v)
   104  	if err != nil {
   105  		t.Fatalf("expected comparison to correct value to not error. got %v", err)
   106  	}
   107  
   108  	v[0] = 1
   109  	err = db.CompareAndStoreAccountID(v)
   110  	if err != errDifferentAccountID {
   111  		t.Fatalf("wrong error. want '%v' got '%v'", errDifferentAccountID, err)
   112  	}
   113  }