2018-05-21 18:47:39 +03:00
|
|
|
package chainntnfs
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"io/ioutil"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
|
|
|
"github.com/btcsuite/btcd/wire"
|
|
|
|
"github.com/lightningnetwork/lnd/channeldb"
|
|
|
|
)
|
|
|
|
|
2018-10-02 00:19:38 +03:00
|
|
|
func initHintCache(t *testing.T) *HeightHintCache {
|
2018-05-21 18:47:39 +03:00
|
|
|
t.Helper()
|
|
|
|
|
|
|
|
tempDir, err := ioutil.TempDir("", "kek")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unable to create temp dir: %v", err)
|
|
|
|
}
|
|
|
|
db, err := channeldb.Open(tempDir)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unable to create db: %v", err)
|
|
|
|
}
|
2020-06-27 04:40:00 +03:00
|
|
|
testCfg := Config{
|
|
|
|
HeightHintCacheQueryDisable: false,
|
|
|
|
}
|
|
|
|
hintCache, err := NewHeightHintCache(testCfg, db)
|
2018-05-21 18:47:39 +03:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unable to create hint cache: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return hintCache
|
|
|
|
}
|
|
|
|
|
|
|
|
// TestHeightHintCacheConfirms ensures that the height hint cache properly
|
|
|
|
// caches confirm hints for transactions.
|
|
|
|
func TestHeightHintCacheConfirms(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
2018-10-02 00:19:38 +03:00
|
|
|
hintCache := initHintCache(t)
|
2018-05-21 18:47:39 +03:00
|
|
|
|
|
|
|
// Querying for a transaction hash not found within the cache should
|
|
|
|
// return an error indication so.
|
|
|
|
var unknownHash chainhash.Hash
|
2018-12-07 08:13:35 +03:00
|
|
|
copy(unknownHash[:], bytes.Repeat([]byte{0x01}, 32))
|
|
|
|
unknownConfRequest := ConfRequest{TxID: unknownHash}
|
|
|
|
_, err := hintCache.QueryConfirmHint(unknownConfRequest)
|
2018-05-21 18:47:39 +03:00
|
|
|
if err != ErrConfirmHintNotFound {
|
|
|
|
t.Fatalf("expected ErrConfirmHintNotFound, got: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now, we'll create some transaction hashes and commit them to the
|
|
|
|
// cache with the same confirm hint.
|
|
|
|
const height = 100
|
|
|
|
const numHashes = 5
|
2018-12-07 08:13:35 +03:00
|
|
|
confRequests := make([]ConfRequest, numHashes)
|
2018-05-21 18:47:39 +03:00
|
|
|
for i := 0; i < numHashes; i++ {
|
|
|
|
var txHash chainhash.Hash
|
2018-12-07 08:13:35 +03:00
|
|
|
copy(txHash[:], bytes.Repeat([]byte{byte(i + 1)}, 32))
|
|
|
|
confRequests[i] = ConfRequest{TxID: txHash}
|
2018-05-21 18:47:39 +03:00
|
|
|
}
|
|
|
|
|
2018-12-07 08:13:35 +03:00
|
|
|
err = hintCache.CommitConfirmHint(height, confRequests...)
|
|
|
|
if err != nil {
|
2018-05-21 18:47:39 +03:00
|
|
|
t.Fatalf("unable to add entries to cache: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// With the hashes committed, we'll now query the cache to ensure that
|
|
|
|
// we're able to properly retrieve the confirm hints.
|
2018-12-07 08:13:35 +03:00
|
|
|
for _, confRequest := range confRequests {
|
|
|
|
confirmHint, err := hintCache.QueryConfirmHint(confRequest)
|
2018-05-21 18:47:39 +03:00
|
|
|
if err != nil {
|
2018-12-07 08:13:35 +03:00
|
|
|
t.Fatalf("unable to query for hint of %v: %v", confRequest, err)
|
2018-05-21 18:47:39 +03:00
|
|
|
}
|
|
|
|
if confirmHint != height {
|
|
|
|
t.Fatalf("expected confirm hint %d, got %d", height,
|
|
|
|
confirmHint)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// We'll also attempt to purge all of them in a single database
|
|
|
|
// transaction.
|
2018-12-07 08:13:35 +03:00
|
|
|
if err := hintCache.PurgeConfirmHint(confRequests...); err != nil {
|
2018-05-21 18:47:39 +03:00
|
|
|
t.Fatalf("unable to remove confirm hints: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Finally, we'll attempt to query for each hash. We should expect not
|
|
|
|
// to find a hint for any of them.
|
2018-12-07 08:13:35 +03:00
|
|
|
for _, confRequest := range confRequests {
|
|
|
|
_, err := hintCache.QueryConfirmHint(confRequest)
|
2018-05-21 18:47:39 +03:00
|
|
|
if err != ErrConfirmHintNotFound {
|
|
|
|
t.Fatalf("expected ErrConfirmHintNotFound, got :%v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// TestHeightHintCacheSpends ensures that the height hint cache properly caches
|
|
|
|
// spend hints for outpoints.
|
|
|
|
func TestHeightHintCacheSpends(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
2018-10-02 00:19:38 +03:00
|
|
|
hintCache := initHintCache(t)
|
2018-05-21 18:47:39 +03:00
|
|
|
|
|
|
|
// Querying for an outpoint not found within the cache should return an
|
|
|
|
// error indication so.
|
2018-12-07 08:13:35 +03:00
|
|
|
unknownOutPoint := wire.OutPoint{Index: 1}
|
|
|
|
unknownSpendRequest := SpendRequest{OutPoint: unknownOutPoint}
|
|
|
|
_, err := hintCache.QuerySpendHint(unknownSpendRequest)
|
2018-05-21 18:47:39 +03:00
|
|
|
if err != ErrSpendHintNotFound {
|
|
|
|
t.Fatalf("expected ErrSpendHintNotFound, got: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now, we'll create some outpoints and commit them to the cache with
|
|
|
|
// the same spend hint.
|
|
|
|
const height = 100
|
|
|
|
const numOutpoints = 5
|
2018-12-07 08:13:35 +03:00
|
|
|
spendRequests := make([]SpendRequest, numOutpoints)
|
2018-05-21 18:47:39 +03:00
|
|
|
for i := uint32(0); i < numOutpoints; i++ {
|
2018-12-07 08:13:35 +03:00
|
|
|
spendRequests[i] = SpendRequest{
|
|
|
|
OutPoint: wire.OutPoint{Index: i + 1},
|
|
|
|
}
|
2018-05-21 18:47:39 +03:00
|
|
|
}
|
|
|
|
|
2018-12-07 08:13:35 +03:00
|
|
|
err = hintCache.CommitSpendHint(height, spendRequests...)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unable to add entries to cache: %v", err)
|
2018-05-21 18:47:39 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// With the outpoints committed, we'll now query the cache to ensure
|
|
|
|
// that we're able to properly retrieve the confirm hints.
|
2018-12-07 08:13:35 +03:00
|
|
|
for _, spendRequest := range spendRequests {
|
|
|
|
spendHint, err := hintCache.QuerySpendHint(spendRequest)
|
2018-05-21 18:47:39 +03:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unable to query for hint: %v", err)
|
|
|
|
}
|
|
|
|
if spendHint != height {
|
|
|
|
t.Fatalf("expected spend hint %d, got %d", height,
|
|
|
|
spendHint)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// We'll also attempt to purge all of them in a single database
|
|
|
|
// transaction.
|
2018-12-07 08:13:35 +03:00
|
|
|
if err := hintCache.PurgeSpendHint(spendRequests...); err != nil {
|
2018-05-21 18:47:39 +03:00
|
|
|
t.Fatalf("unable to remove spend hint: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Finally, we'll attempt to query for each outpoint. We should expect
|
|
|
|
// not to find a hint for any of them.
|
2018-12-07 08:13:35 +03:00
|
|
|
for _, spendRequest := range spendRequests {
|
|
|
|
_, err = hintCache.QuerySpendHint(spendRequest)
|
2018-05-21 18:47:39 +03:00
|
|
|
if err != ErrSpendHintNotFound {
|
|
|
|
t.Fatalf("expected ErrSpendHintNotFound, got: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|