height_hint_test.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. package channeldb
  2. import (
  3. "bytes"
  4. "testing"
  5. "github.com/btcsuite/btcd/chaincfg/chainhash"
  6. "github.com/btcsuite/btcd/wire"
  7. "github.com/lightningnetwork/lnd/chainntnfs"
  8. "github.com/stretchr/testify/require"
  9. )
  10. func initHintCache(t *testing.T) *HeightHintCache {
  11. t.Helper()
  12. defaultCfg := CacheConfig{
  13. QueryDisable: false,
  14. }
  15. return initHintCacheWithConfig(t, defaultCfg)
  16. }
  17. func initHintCacheWithConfig(t *testing.T, cfg CacheConfig) *HeightHintCache {
  18. t.Helper()
  19. db, err := Open(t.TempDir())
  20. require.NoError(t, err, "unable to create db")
  21. hintCache, err := NewHeightHintCache(cfg, db.Backend)
  22. require.NoError(t, err, "unable to create hint cache")
  23. t.Cleanup(func() {
  24. require.NoError(t, db.Close())
  25. })
  26. return hintCache
  27. }
  28. // TestHeightHintCacheConfirms ensures that the height hint cache properly
  29. // caches confirm hints for transactions.
  30. func TestHeightHintCacheConfirms(t *testing.T) {
  31. t.Parallel()
  32. hintCache := initHintCache(t)
  33. // Querying for a transaction hash not found within the cache should
  34. // return an error indication so.
  35. var unknownHash chainhash.Hash
  36. copy(unknownHash[:], bytes.Repeat([]byte{0x01}, 32))
  37. unknownConfRequest := chainntnfs.ConfRequest{TxID: unknownHash}
  38. _, err := hintCache.QueryConfirmHint(unknownConfRequest)
  39. require.ErrorIs(t, err, chainntnfs.ErrConfirmHintNotFound)
  40. // Now, we'll create some transaction hashes and commit them to the
  41. // cache with the same confirm hint.
  42. const height = 100
  43. const numHashes = 5
  44. confRequests := make([]chainntnfs.ConfRequest, numHashes)
  45. for i := 0; i < numHashes; i++ {
  46. var txHash chainhash.Hash
  47. copy(txHash[:], bytes.Repeat([]byte{byte(i + 1)}, 32))
  48. confRequests[i] = chainntnfs.ConfRequest{TxID: txHash}
  49. }
  50. err = hintCache.CommitConfirmHint(height, confRequests...)
  51. require.NoError(t, err, "unable to add entries to cache")
  52. // With the hashes committed, we'll now query the cache to ensure that
  53. // we're able to properly retrieve the confirm hints.
  54. for _, confRequest := range confRequests {
  55. confirmHint, err := hintCache.QueryConfirmHint(confRequest)
  56. require.NoError(t, err)
  57. require.EqualValues(t, height, confirmHint)
  58. }
  59. // We'll also attempt to purge all of them in a single database
  60. // transaction.
  61. err = hintCache.PurgeConfirmHint(confRequests...)
  62. require.NoError(t, err)
  63. // Finally, we'll attempt to query for each hash. We should expect not
  64. // to find a hint for any of them.
  65. for _, confRequest := range confRequests {
  66. _, err := hintCache.QueryConfirmHint(confRequest)
  67. require.ErrorIs(t, err, chainntnfs.ErrConfirmHintNotFound)
  68. }
  69. }
  70. // TestHeightHintCacheSpends ensures that the height hint cache properly caches
  71. // spend hints for outpoints.
  72. func TestHeightHintCacheSpends(t *testing.T) {
  73. t.Parallel()
  74. hintCache := initHintCache(t)
  75. // Querying for an outpoint not found within the cache should return an
  76. // error indication so.
  77. unknownOutPoint := wire.OutPoint{Index: 1}
  78. unknownSpendRequest := chainntnfs.SpendRequest{
  79. OutPoint: unknownOutPoint,
  80. }
  81. _, err := hintCache.QuerySpendHint(unknownSpendRequest)
  82. require.ErrorIs(t, err, chainntnfs.ErrSpendHintNotFound)
  83. // Now, we'll create some outpoints and commit them to the cache with
  84. // the same spend hint.
  85. const height = 100
  86. const numOutpoints = 5
  87. spendRequests := make([]chainntnfs.SpendRequest, numOutpoints)
  88. for i := uint32(0); i < numOutpoints; i++ {
  89. spendRequests[i] = chainntnfs.SpendRequest{
  90. OutPoint: wire.OutPoint{Index: i + 1},
  91. }
  92. }
  93. err = hintCache.CommitSpendHint(height, spendRequests...)
  94. require.NoError(t, err, "unable to add entries to cache")
  95. // With the outpoints committed, we'll now query the cache to ensure
  96. // that we're able to properly retrieve the confirm hints.
  97. for _, spendRequest := range spendRequests {
  98. spendHint, err := hintCache.QuerySpendHint(spendRequest)
  99. require.NoError(t, err)
  100. require.EqualValues(t, height, spendHint)
  101. }
  102. // We'll also attempt to purge all of them in a single database
  103. // transaction.
  104. err = hintCache.PurgeSpendHint(spendRequests...)
  105. require.NoError(t, err)
  106. // Finally, we'll attempt to query for each outpoint. We should expect
  107. // not to find a hint for any of them.
  108. for _, spendRequest := range spendRequests {
  109. _, err = hintCache.QuerySpendHint(spendRequest)
  110. require.ErrorIs(t, err, chainntnfs.ErrSpendHintNotFound)
  111. }
  112. }
  113. // TestQueryDisable asserts querying for confirmation or spend hints always
  114. // return height zero when QueryDisabled is set to true in the CacheConfig.
  115. func TestQueryDisable(t *testing.T) {
  116. cfg := CacheConfig{
  117. QueryDisable: true,
  118. }
  119. hintCache := initHintCacheWithConfig(t, cfg)
  120. // Insert a new confirmation hint with a non-zero height.
  121. const confHeight = 100
  122. confRequest := chainntnfs.ConfRequest{
  123. TxID: chainhash.Hash{0x01, 0x02, 0x03},
  124. }
  125. err := hintCache.CommitConfirmHint(confHeight, confRequest)
  126. require.Nil(t, err)
  127. // Query for the confirmation hint, which should return zero.
  128. cachedConfHeight, err := hintCache.QueryConfirmHint(confRequest)
  129. require.Nil(t, err)
  130. require.Equal(t, uint32(0), cachedConfHeight)
  131. // Insert a new spend hint with a non-zero height.
  132. const spendHeight = 200
  133. spendRequest := chainntnfs.SpendRequest{
  134. OutPoint: wire.OutPoint{
  135. Hash: chainhash.Hash{0x4, 0x05, 0x06},
  136. Index: 42,
  137. },
  138. }
  139. err = hintCache.CommitSpendHint(spendHeight, spendRequest)
  140. require.Nil(t, err)
  141. // Query for the spend hint, which should return zero.
  142. cachedSpendHeight, err := hintCache.QuerySpendHint(spendRequest)
  143. require.Nil(t, err)
  144. require.Equal(t, uint32(0), cachedSpendHeight)
  145. }