Merge pull request #2044 from wpaulino/enable-height-hint-cache
chainntnfs: re-enable height hint cache
This commit is contained in:
commit
c3546c280d
@ -568,14 +568,19 @@ func (b *BitcoindNotifier) confDetailsManually(txid *chainhash.Hash,
|
|||||||
// transactions included this block will processed to either send notifications
|
// transactions included this block will processed to either send notifications
|
||||||
// now or after numConfirmations confs.
|
// now or after numConfirmations confs.
|
||||||
func (b *BitcoindNotifier) handleBlockConnected(block chainntnfs.BlockEpoch) error {
|
func (b *BitcoindNotifier) handleBlockConnected(block chainntnfs.BlockEpoch) error {
|
||||||
|
// First, we'll fetch the raw block as we'll need to gather all the
|
||||||
|
// transactions to determine whether any are relevant to our registered
|
||||||
|
// clients.
|
||||||
rawBlock, err := b.chainConn.GetBlock(block.Hash)
|
rawBlock, err := b.chainConn.GetBlock(block.Hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to get block: %v", err)
|
return fmt.Errorf("unable to get block: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
txns := btcutil.NewBlock(rawBlock).Transactions()
|
txns := btcutil.NewBlock(rawBlock).Transactions()
|
||||||
err = b.txNotifier.ConnectTip(
|
|
||||||
block.Hash, uint32(block.Height), txns)
|
// We'll then extend the txNotifier's height with the information of
|
||||||
|
// this new block, which will handle all of the notification logic for
|
||||||
|
// us.
|
||||||
|
err = b.txNotifier.ConnectTip(block.Hash, uint32(block.Height), txns)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to connect tip: %v", err)
|
return fmt.Errorf("unable to connect tip: %v", err)
|
||||||
}
|
}
|
||||||
@ -583,15 +588,15 @@ func (b *BitcoindNotifier) handleBlockConnected(block chainntnfs.BlockEpoch) err
|
|||||||
chainntnfs.Log.Infof("New block: height=%v, sha=%v", block.Height,
|
chainntnfs.Log.Infof("New block: height=%v, sha=%v", block.Height,
|
||||||
block.Hash)
|
block.Hash)
|
||||||
|
|
||||||
// We want to set the best block before dispatching notifications so
|
// Now that we've guaranteed the new block extends the txNotifier's
|
||||||
// if any subscribers make queries based on their received block epoch,
|
// current tip, we'll proceed to dispatch notifications to all of our
|
||||||
// our state is fully updated in time.
|
// registered clients whom have had notifications fulfilled. Before
|
||||||
|
// doing so, we'll make sure update our in memory state in order to
|
||||||
|
// satisfy any client requests based upon the new block.
|
||||||
b.bestBlock = block
|
b.bestBlock = block
|
||||||
|
|
||||||
// Lastly we'll notify any subscribed clients of the block.
|
|
||||||
b.notifyBlockEpochs(block.Height, block.Hash)
|
b.notifyBlockEpochs(block.Height, block.Hash)
|
||||||
|
return b.txNotifier.NotifyHeight(uint32(block.Height))
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// notifyBlockEpochs notifies all registered block epoch clients of the newly
|
// notifyBlockEpochs notifies all registered block epoch clients of the newly
|
||||||
|
@ -25,7 +25,7 @@ func initHintCache(t *testing.T) *chainntnfs.HeightHintCache {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to create db: %v", err)
|
t.Fatalf("unable to create db: %v", err)
|
||||||
}
|
}
|
||||||
hintCache, err := chainntnfs.NewHeightHintCache(db, true)
|
hintCache, err := chainntnfs.NewHeightHintCache(db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to create hint cache: %v", err)
|
t.Fatalf("unable to create hint cache: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -622,14 +622,13 @@ func (b *BtcdNotifier) confDetailsManually(txid *chainhash.Hash, startHeight,
|
|||||||
// TODO(halseth): this is reusing the neutrino notifier implementation, unify
|
// TODO(halseth): this is reusing the neutrino notifier implementation, unify
|
||||||
// them.
|
// them.
|
||||||
func (b *BtcdNotifier) handleBlockConnected(epoch chainntnfs.BlockEpoch) error {
|
func (b *BtcdNotifier) handleBlockConnected(epoch chainntnfs.BlockEpoch) error {
|
||||||
// First process the block for our internal state. A new block has
|
// First, we'll fetch the raw block as we'll need to gather all the
|
||||||
// been connected to the main chain. Send out any N confirmation
|
// transactions to determine whether any are relevant to our registered
|
||||||
// notifications which may have been triggered by this new block.
|
// clients.
|
||||||
rawBlock, err := b.chainConn.GetBlock(epoch.Hash)
|
rawBlock, err := b.chainConn.GetBlock(epoch.Hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to get block: %v", err)
|
return fmt.Errorf("unable to get block: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
newBlock := &filteredBlock{
|
newBlock := &filteredBlock{
|
||||||
hash: *epoch.Hash,
|
hash: *epoch.Hash,
|
||||||
height: uint32(epoch.Height),
|
height: uint32(epoch.Height),
|
||||||
@ -637,6 +636,9 @@ func (b *BtcdNotifier) handleBlockConnected(epoch chainntnfs.BlockEpoch) error {
|
|||||||
connect: true,
|
connect: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We'll then extend the txNotifier's height with the information of
|
||||||
|
// this new block, which will handle all of the notification logic for
|
||||||
|
// us.
|
||||||
err = b.txNotifier.ConnectTip(
|
err = b.txNotifier.ConnectTip(
|
||||||
&newBlock.hash, newBlock.height, newBlock.txns,
|
&newBlock.hash, newBlock.height, newBlock.txns,
|
||||||
)
|
)
|
||||||
@ -647,13 +649,15 @@ func (b *BtcdNotifier) handleBlockConnected(epoch chainntnfs.BlockEpoch) error {
|
|||||||
chainntnfs.Log.Infof("New block: height=%v, sha=%v", epoch.Height,
|
chainntnfs.Log.Infof("New block: height=%v, sha=%v", epoch.Height,
|
||||||
epoch.Hash)
|
epoch.Hash)
|
||||||
|
|
||||||
// We want to set the best block before dispatching notifications so if
|
// Now that we've guaranteed the new block extends the txNotifier's
|
||||||
// any subscribers make queries based on their received block epoch, our
|
// current tip, we'll proceed to dispatch notifications to all of our
|
||||||
// state is fully updated in time.
|
// registered clients whom have had notifications fulfilled. Before
|
||||||
|
// doing so, we'll make sure update our in memory state in order to
|
||||||
|
// satisfy any client requests based upon the new block.
|
||||||
b.bestBlock = epoch
|
b.bestBlock = epoch
|
||||||
b.notifyBlockEpochs(int32(newBlock.height), &newBlock.hash)
|
|
||||||
|
|
||||||
return nil
|
b.notifyBlockEpochs(epoch.Height, epoch.Hash)
|
||||||
|
return b.txNotifier.NotifyHeight(uint32(epoch.Height))
|
||||||
}
|
}
|
||||||
|
|
||||||
// notifyBlockEpochs notifies all registered block epoch clients of the newly
|
// notifyBlockEpochs notifies all registered block epoch clients of the newly
|
||||||
|
@ -23,7 +23,7 @@ func initHintCache(t *testing.T) *chainntnfs.HeightHintCache {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to create db: %v", err)
|
t.Fatalf("unable to create db: %v", err)
|
||||||
}
|
}
|
||||||
hintCache, err := chainntnfs.NewHeightHintCache(db, true)
|
hintCache, err := chainntnfs.NewHeightHintCache(db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to create hint cache: %v", err)
|
t.Fatalf("unable to create hint cache: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,6 @@ type ConfirmHintCache interface {
|
|||||||
// will be stored.
|
// will be stored.
|
||||||
type HeightHintCache struct {
|
type HeightHintCache struct {
|
||||||
db *channeldb.DB
|
db *channeldb.DB
|
||||||
disabled bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compile-time checks to ensure HeightHintCache satisfies the SpendHintCache
|
// Compile-time checks to ensure HeightHintCache satisfies the SpendHintCache
|
||||||
@ -95,11 +94,8 @@ var _ SpendHintCache = (*HeightHintCache)(nil)
|
|||||||
var _ ConfirmHintCache = (*HeightHintCache)(nil)
|
var _ ConfirmHintCache = (*HeightHintCache)(nil)
|
||||||
|
|
||||||
// NewHeightHintCache returns a new height hint cache backed by a database.
|
// NewHeightHintCache returns a new height hint cache backed by a database.
|
||||||
func NewHeightHintCache(db *channeldb.DB, disable bool) (*HeightHintCache, error) {
|
func NewHeightHintCache(db *channeldb.DB) (*HeightHintCache, error) {
|
||||||
cache := &HeightHintCache{
|
cache := &HeightHintCache{db}
|
||||||
db: db,
|
|
||||||
disabled: disable,
|
|
||||||
}
|
|
||||||
if err := cache.initBuckets(); err != nil {
|
if err := cache.initBuckets(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -123,10 +119,6 @@ func (c *HeightHintCache) initBuckets() error {
|
|||||||
|
|
||||||
// CommitSpendHint commits a spend hint for the outpoints to the cache.
|
// CommitSpendHint commits a spend hint for the outpoints to the cache.
|
||||||
func (c *HeightHintCache) CommitSpendHint(height uint32, ops ...wire.OutPoint) error {
|
func (c *HeightHintCache) CommitSpendHint(height uint32, ops ...wire.OutPoint) error {
|
||||||
if c.disabled {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(ops) == 0 {
|
if len(ops) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -165,10 +157,6 @@ func (c *HeightHintCache) CommitSpendHint(height uint32, ops ...wire.OutPoint) e
|
|||||||
// ErrSpendHintNotFound is returned if a spend hint does not exist within the
|
// ErrSpendHintNotFound is returned if a spend hint does not exist within the
|
||||||
// cache for the outpoint.
|
// cache for the outpoint.
|
||||||
func (c *HeightHintCache) QuerySpendHint(op wire.OutPoint) (uint32, error) {
|
func (c *HeightHintCache) QuerySpendHint(op wire.OutPoint) (uint32, error) {
|
||||||
if c.disabled {
|
|
||||||
return 0, ErrSpendHintNotFound
|
|
||||||
}
|
|
||||||
|
|
||||||
var hint uint32
|
var hint uint32
|
||||||
err := c.db.View(func(tx *bolt.Tx) error {
|
err := c.db.View(func(tx *bolt.Tx) error {
|
||||||
spendHints := tx.Bucket(spendHintBucket)
|
spendHints := tx.Bucket(spendHintBucket)
|
||||||
@ -197,10 +185,6 @@ func (c *HeightHintCache) QuerySpendHint(op wire.OutPoint) (uint32, error) {
|
|||||||
|
|
||||||
// PurgeSpendHint removes the spend hint for the outpoints from the cache.
|
// PurgeSpendHint removes the spend hint for the outpoints from the cache.
|
||||||
func (c *HeightHintCache) PurgeSpendHint(ops ...wire.OutPoint) error {
|
func (c *HeightHintCache) PurgeSpendHint(ops ...wire.OutPoint) error {
|
||||||
if c.disabled {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(ops) == 0 {
|
if len(ops) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -232,10 +216,6 @@ func (c *HeightHintCache) PurgeSpendHint(ops ...wire.OutPoint) error {
|
|||||||
|
|
||||||
// CommitConfirmHint commits a confirm hint for the transactions to the cache.
|
// CommitConfirmHint commits a confirm hint for the transactions to the cache.
|
||||||
func (c *HeightHintCache) CommitConfirmHint(height uint32, txids ...chainhash.Hash) error {
|
func (c *HeightHintCache) CommitConfirmHint(height uint32, txids ...chainhash.Hash) error {
|
||||||
if c.disabled {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(txids) == 0 {
|
if len(txids) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -274,10 +254,6 @@ func (c *HeightHintCache) CommitConfirmHint(height uint32, txids ...chainhash.Ha
|
|||||||
// ErrConfirmHintNotFound is returned if a confirm hint does not exist within
|
// ErrConfirmHintNotFound is returned if a confirm hint does not exist within
|
||||||
// the cache for the transaction hash.
|
// the cache for the transaction hash.
|
||||||
func (c *HeightHintCache) QueryConfirmHint(txid chainhash.Hash) (uint32, error) {
|
func (c *HeightHintCache) QueryConfirmHint(txid chainhash.Hash) (uint32, error) {
|
||||||
if c.disabled {
|
|
||||||
return 0, ErrConfirmHintNotFound
|
|
||||||
}
|
|
||||||
|
|
||||||
var hint uint32
|
var hint uint32
|
||||||
err := c.db.View(func(tx *bolt.Tx) error {
|
err := c.db.View(func(tx *bolt.Tx) error {
|
||||||
confirmHints := tx.Bucket(confirmHintBucket)
|
confirmHints := tx.Bucket(confirmHintBucket)
|
||||||
@ -307,10 +283,6 @@ func (c *HeightHintCache) QueryConfirmHint(txid chainhash.Hash) (uint32, error)
|
|||||||
// PurgeConfirmHint removes the confirm hint for the transactions from the
|
// PurgeConfirmHint removes the confirm hint for the transactions from the
|
||||||
// cache.
|
// cache.
|
||||||
func (c *HeightHintCache) PurgeConfirmHint(txids ...chainhash.Hash) error {
|
func (c *HeightHintCache) PurgeConfirmHint(txids ...chainhash.Hash) error {
|
||||||
if c.disabled {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(txids) == 0 {
|
if len(txids) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ import (
|
|||||||
"github.com/lightningnetwork/lnd/channeldb"
|
"github.com/lightningnetwork/lnd/channeldb"
|
||||||
)
|
)
|
||||||
|
|
||||||
func initHintCache(t *testing.T, disable bool) *HeightHintCache {
|
func initHintCache(t *testing.T) *HeightHintCache {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
tempDir, err := ioutil.TempDir("", "kek")
|
tempDir, err := ioutil.TempDir("", "kek")
|
||||||
@ -21,7 +21,7 @@ func initHintCache(t *testing.T, disable bool) *HeightHintCache {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to create db: %v", err)
|
t.Fatalf("unable to create db: %v", err)
|
||||||
}
|
}
|
||||||
hintCache, err := NewHeightHintCache(db, disable)
|
hintCache, err := NewHeightHintCache(db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to create hint cache: %v", err)
|
t.Fatalf("unable to create hint cache: %v", err)
|
||||||
}
|
}
|
||||||
@ -34,7 +34,7 @@ func initHintCache(t *testing.T, disable bool) *HeightHintCache {
|
|||||||
func TestHeightHintCacheConfirms(t *testing.T) {
|
func TestHeightHintCacheConfirms(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
hintCache := initHintCache(t, false)
|
hintCache := initHintCache(t)
|
||||||
|
|
||||||
// Querying for a transaction hash not found within the cache should
|
// Querying for a transaction hash not found within the cache should
|
||||||
// return an error indication so.
|
// return an error indication so.
|
||||||
@ -93,7 +93,7 @@ func TestHeightHintCacheConfirms(t *testing.T) {
|
|||||||
func TestHeightHintCacheSpends(t *testing.T) {
|
func TestHeightHintCacheSpends(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
hintCache := initHintCache(t, false)
|
hintCache := initHintCache(t)
|
||||||
|
|
||||||
// Querying for an outpoint not found within the cache should return an
|
// Querying for an outpoint not found within the cache should return an
|
||||||
// error indication so.
|
// error indication so.
|
||||||
@ -146,76 +146,3 @@ func TestHeightHintCacheSpends(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestHeightHintCacheDisabled asserts that a disabled height hint cache never
|
|
||||||
// returns spend or confirm hints that are committed.
|
|
||||||
func TestHeightHintCacheDisabled(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
const height uint32 = 100
|
|
||||||
|
|
||||||
// Create a disabled height hint cache.
|
|
||||||
hintCache := initHintCache(t, true)
|
|
||||||
|
|
||||||
// Querying a disabled cache w/ no spend hint should return not found.
|
|
||||||
var outpoint wire.OutPoint
|
|
||||||
_, err := hintCache.QuerySpendHint(outpoint)
|
|
||||||
if err != ErrSpendHintNotFound {
|
|
||||||
t.Fatalf("expected ErrSpendHintNotFound, got: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Commit a spend hint to the disabled cache, which should be a noop.
|
|
||||||
if err := hintCache.CommitSpendHint(height, outpoint); err != nil {
|
|
||||||
t.Fatalf("unable to commit spend hint: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Querying a disabled cache after commit noop should return not found.
|
|
||||||
_, err = hintCache.QuerySpendHint(outpoint)
|
|
||||||
if err != ErrSpendHintNotFound {
|
|
||||||
t.Fatalf("expected ErrSpendHintNotFound, got: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reenable the cache, this time actually committing a spend hint.
|
|
||||||
hintCache.disabled = false
|
|
||||||
if err := hintCache.CommitSpendHint(height, outpoint); err != nil {
|
|
||||||
t.Fatalf("unable to commit spend hint: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disable the cache again, spend hint should not be found.
|
|
||||||
hintCache.disabled = true
|
|
||||||
_, err = hintCache.QuerySpendHint(outpoint)
|
|
||||||
if err != ErrSpendHintNotFound {
|
|
||||||
t.Fatalf("expected ErrSpendHintNotFound, got: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Querying a disabled cache w/ no conf hint should return not found.
|
|
||||||
var txid chainhash.Hash
|
|
||||||
_, err = hintCache.QueryConfirmHint(txid)
|
|
||||||
if err != ErrConfirmHintNotFound {
|
|
||||||
t.Fatalf("expected ErrConfirmHintNotFound, got: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Commit a conf hint to the disabled cache, which should be a noop.
|
|
||||||
if err := hintCache.CommitConfirmHint(height, txid); err != nil {
|
|
||||||
t.Fatalf("unable to commit spend hint: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Querying a disabled cache after commit noop should return not found.
|
|
||||||
_, err = hintCache.QueryConfirmHint(txid)
|
|
||||||
if err != ErrConfirmHintNotFound {
|
|
||||||
t.Fatalf("expected ErrConfirmHintNotFound, got: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reenable the cache, this time actually committing a conf hint.
|
|
||||||
hintCache.disabled = false
|
|
||||||
if err := hintCache.CommitConfirmHint(height, txid); err != nil {
|
|
||||||
t.Fatalf("unable to commit spend hint: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disable the cache again, conf hint should not be found.
|
|
||||||
hintCache.disabled = true
|
|
||||||
_, err = hintCache.QueryConfirmHint(txid)
|
|
||||||
if err != ErrConfirmHintNotFound {
|
|
||||||
t.Fatalf("expected ErrConfirmHintNotFound, got: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1758,7 +1758,7 @@ func TestInterfaces(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to create db: %v", err)
|
t.Fatalf("unable to create db: %v", err)
|
||||||
}
|
}
|
||||||
hintCache, err := chainntnfs.NewHeightHintCache(db, true)
|
hintCache, err := chainntnfs.NewHeightHintCache(db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to create height hint cache: %v", err)
|
t.Fatalf("unable to create height hint cache: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -542,9 +542,8 @@ func (n *NeutrinoNotifier) historicalConfDetails(targetHash *chainhash.Hash,
|
|||||||
// transactions included this block will processed to either send notifications
|
// transactions included this block will processed to either send notifications
|
||||||
// now or after numConfirmations confs.
|
// now or after numConfirmations confs.
|
||||||
func (n *NeutrinoNotifier) handleBlockConnected(newBlock *filteredBlock) error {
|
func (n *NeutrinoNotifier) handleBlockConnected(newBlock *filteredBlock) error {
|
||||||
// First process the block for our internal state. A new block has
|
// We'll extend the txNotifier's height with the information of this new
|
||||||
// been connected to the main chain. Send out any N confirmation
|
// block, which will handle all of the notification logic for us.
|
||||||
// notifications which may have been triggered by this new block.
|
|
||||||
err := n.txNotifier.ConnectTip(
|
err := n.txNotifier.ConnectTip(
|
||||||
&newBlock.hash, newBlock.height, newBlock.txns,
|
&newBlock.hash, newBlock.height, newBlock.txns,
|
||||||
)
|
)
|
||||||
@ -555,16 +554,15 @@ func (n *NeutrinoNotifier) handleBlockConnected(newBlock *filteredBlock) error {
|
|||||||
chainntnfs.Log.Infof("New block: height=%v, sha=%v", newBlock.height,
|
chainntnfs.Log.Infof("New block: height=%v, sha=%v", newBlock.height,
|
||||||
newBlock.hash)
|
newBlock.hash)
|
||||||
|
|
||||||
// We want to set the best block before dispatching notifications
|
// Now that we've guaranteed the new block extends the txNotifier's
|
||||||
// so if any subscribers make queries based on their received
|
// current tip, we'll proceed to dispatch notifications to all of our
|
||||||
// block epoch, our state is fully updated in time.
|
// registered clients whom have had notifications fulfilled. Before
|
||||||
|
// doing so, we'll make sure update our in memory state in order to
|
||||||
|
// satisfy any client requests based upon the new block.
|
||||||
n.bestHeight = newBlock.height
|
n.bestHeight = newBlock.height
|
||||||
|
|
||||||
// With all persistent changes committed, notify any subscribed clients
|
|
||||||
// of the block.
|
|
||||||
n.notifyBlockEpochs(int32(newBlock.height), &newBlock.hash)
|
n.notifyBlockEpochs(int32(newBlock.height), &newBlock.hash)
|
||||||
|
return n.txNotifier.NotifyHeight(newBlock.height)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// getFilteredBlock is a utility to retrieve the full filtered block from a block epoch.
|
// getFilteredBlock is a utility to retrieve the full filtered block from a block epoch.
|
||||||
|
@ -887,9 +887,13 @@ func (n *TxNotifier) dispatchSpendDetails(ntfn *SpendNtfn, details *SpendDetail)
|
|||||||
// confirmation registration for.
|
// confirmation registration for.
|
||||||
//
|
//
|
||||||
// In the event that the transaction is relevant, a confirmation/spend
|
// In the event that the transaction is relevant, a confirmation/spend
|
||||||
// notification will be dispatched to the relevant clients. Confirmation
|
// notification will be queued for dispatch to the relevant clients.
|
||||||
// notifications will only be dispatched for transactions that have met the
|
// Confirmation notifications will only be dispatched for transactions that have
|
||||||
// required number of confirmations required by the client.
|
// met the required number of confirmations required by the client.
|
||||||
|
//
|
||||||
|
// NOTE: In order to actually dispatch the relevant transaction notifications to
|
||||||
|
// clients, NotifyHeight must be called with the same block height in order to
|
||||||
|
// maintain correctness.
|
||||||
func (n *TxNotifier) ConnectTip(blockHash *chainhash.Hash, blockHeight uint32,
|
func (n *TxNotifier) ConnectTip(blockHash *chainhash.Hash, blockHeight uint32,
|
||||||
txns []*btcutil.Tx) error {
|
txns []*btcutil.Tx) error {
|
||||||
|
|
||||||
@ -1017,14 +1021,24 @@ func (n *TxNotifier) ConnectTip(blockHash *chainhash.Hash, blockHeight uint32,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now that we've determined which transactions were confirmed and which
|
// Finally, now that we've determined which transactions were confirmed
|
||||||
// outpoints were spent within the new block, we can update their
|
// and which outpoints were spent within the new block, we can update
|
||||||
// entries in their respective caches, along with all of our unconfirmed
|
// their entries in their respective caches, along with all of our
|
||||||
// transactions and unspent outpoints.
|
// unconfirmed transactions and unspent outpoints.
|
||||||
n.updateHints(blockHeight)
|
n.updateHints(blockHeight)
|
||||||
|
|
||||||
// Next, we'll dispatch an update to all of the notification clients for
|
return nil
|
||||||
// our watched transactions with the number of confirmations left at
|
}
|
||||||
|
|
||||||
|
// NotifyHeight dispatches confirmation and spend notifications to the clients
|
||||||
|
// who registered for a notification which has been fulfilled at the passed
|
||||||
|
// height.
|
||||||
|
func (n *TxNotifier) NotifyHeight(height uint32) error {
|
||||||
|
n.Lock()
|
||||||
|
defer n.Unlock()
|
||||||
|
|
||||||
|
// First, we'll dispatch an update to all of the notification clients
|
||||||
|
// for our watched transactions with the number of confirmations left at
|
||||||
// this new height.
|
// this new height.
|
||||||
for _, txHashes := range n.txsByInitialHeight {
|
for _, txHashes := range n.txsByInitialHeight {
|
||||||
for txHash := range txHashes {
|
for txHash := range txHashes {
|
||||||
@ -1032,7 +1046,7 @@ func (n *TxNotifier) ConnectTip(blockHash *chainhash.Hash, blockHeight uint32,
|
|||||||
for _, ntfn := range confSet.ntfns {
|
for _, ntfn := range confSet.ntfns {
|
||||||
txConfHeight := confSet.details.BlockHeight +
|
txConfHeight := confSet.details.BlockHeight +
|
||||||
ntfn.NumConfirmations - 1
|
ntfn.NumConfirmations - 1
|
||||||
numConfsLeft := txConfHeight - blockHeight
|
numConfsLeft := txConfHeight - height
|
||||||
|
|
||||||
// Since we don't clear notifications until
|
// Since we don't clear notifications until
|
||||||
// transactions are no longer under the risk of
|
// transactions are no longer under the risk of
|
||||||
@ -1054,7 +1068,7 @@ func (n *TxNotifier) ConnectTip(blockHash *chainhash.Hash, blockHeight uint32,
|
|||||||
|
|
||||||
// Then, we'll dispatch notifications for all the transactions that have
|
// Then, we'll dispatch notifications for all the transactions that have
|
||||||
// become confirmed at this new block height.
|
// become confirmed at this new block height.
|
||||||
for ntfn := range n.ntfnsByConfirmHeight[blockHeight] {
|
for ntfn := range n.ntfnsByConfirmHeight[height] {
|
||||||
confSet := n.confNotifications[*ntfn.TxID]
|
confSet := n.confNotifications[*ntfn.TxID]
|
||||||
|
|
||||||
Log.Infof("Dispatching %v conf notification for %v",
|
Log.Infof("Dispatching %v conf notification for %v",
|
||||||
@ -1067,11 +1081,11 @@ func (n *TxNotifier) ConnectTip(blockHash *chainhash.Hash, blockHeight uint32,
|
|||||||
return ErrTxNotifierExiting
|
return ErrTxNotifierExiting
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete(n.ntfnsByConfirmHeight, blockHeight)
|
delete(n.ntfnsByConfirmHeight, height)
|
||||||
|
|
||||||
// We'll also dispatch spend notifications for all the outpoints that
|
// We'll also dispatch spend notifications for all the outpoints that
|
||||||
// were spent at this new block height.
|
// were spent at this new block height.
|
||||||
for op := range n.opsBySpendHeight[blockHeight] {
|
for op := range n.opsBySpendHeight[height] {
|
||||||
spendSet := n.spendNotifications[op]
|
spendSet := n.spendNotifications[op]
|
||||||
for _, ntfn := range spendSet.ntfns {
|
for _, ntfn := range spendSet.ntfns {
|
||||||
err := n.dispatchSpendDetails(ntfn, spendSet.details)
|
err := n.dispatchSpendDetails(ntfn, spendSet.details)
|
||||||
@ -1084,8 +1098,8 @@ func (n *TxNotifier) ConnectTip(blockHash *chainhash.Hash, blockHeight uint32,
|
|||||||
// Finally, we'll clear the entries from our set of notifications for
|
// Finally, we'll clear the entries from our set of notifications for
|
||||||
// transactions and outpoints that are no longer under the risk of being
|
// transactions and outpoints that are no longer under the risk of being
|
||||||
// reorged out of the chain.
|
// reorged out of the chain.
|
||||||
if blockHeight >= n.reorgSafetyLimit {
|
if height >= n.reorgSafetyLimit {
|
||||||
matureBlockHeight := blockHeight - n.reorgSafetyLimit
|
matureBlockHeight := height - n.reorgSafetyLimit
|
||||||
for tx := range n.txsByInitialHeight[matureBlockHeight] {
|
for tx := range n.txsByInitialHeight[matureBlockHeight] {
|
||||||
delete(n.confNotifications, tx)
|
delete(n.confNotifications, tx)
|
||||||
}
|
}
|
||||||
|
@ -165,12 +165,13 @@ func TestTxNotifierFutureConfDispatch(t *testing.T) {
|
|||||||
Transactions: []*wire.MsgTx{&tx1, &tx2, &tx3},
|
Transactions: []*wire.MsgTx{&tx1, &tx2, &tx3},
|
||||||
})
|
})
|
||||||
|
|
||||||
err := n.ConnectTip(
|
err := n.ConnectTip(block1.Hash(), 11, block1.Transactions())
|
||||||
block1.Hash(), 11, block1.Transactions(),
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to connect block: %v", err)
|
t.Fatalf("Failed to connect block: %v", err)
|
||||||
}
|
}
|
||||||
|
if err := n.NotifyHeight(11); err != nil {
|
||||||
|
t.Fatalf("unable to dispatch notifications: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
// We should only receive one update for tx1 since it only requires
|
// We should only receive one update for tx1 since it only requires
|
||||||
// one confirmation and it already met it.
|
// one confirmation and it already met it.
|
||||||
@ -232,6 +233,9 @@ func TestTxNotifierFutureConfDispatch(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to connect block: %v", err)
|
t.Fatalf("Failed to connect block: %v", err)
|
||||||
}
|
}
|
||||||
|
if err := n.NotifyHeight(12); err != nil {
|
||||||
|
t.Fatalf("unable to dispatch notifications: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
// We should not receive any event notifications for tx1 since it has
|
// We should not receive any event notifications for tx1 since it has
|
||||||
// already been confirmed.
|
// already been confirmed.
|
||||||
@ -388,6 +392,9 @@ func TestTxNotifierHistoricalConfDispatch(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to connect block: %v", err)
|
t.Fatalf("Failed to connect block: %v", err)
|
||||||
}
|
}
|
||||||
|
if err := n.NotifyHeight(11); err != nil {
|
||||||
|
t.Fatalf("unable to dispatch notifications: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
// We should not receive any event notifications for tx1 since it has
|
// We should not receive any event notifications for tx1 since it has
|
||||||
// already been confirmed.
|
// already been confirmed.
|
||||||
@ -462,6 +469,9 @@ func TestTxNotifierFutureSpendDispatch(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to connect block: %v", err)
|
t.Fatalf("unable to connect block: %v", err)
|
||||||
}
|
}
|
||||||
|
if err := n.NotifyHeight(11); err != nil {
|
||||||
|
t.Fatalf("unable to dispatch notifications: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
expectedSpendDetails := &chainntnfs.SpendDetail{
|
expectedSpendDetails := &chainntnfs.SpendDetail{
|
||||||
SpentOutPoint: &ntfn.OutPoint,
|
SpentOutPoint: &ntfn.OutPoint,
|
||||||
@ -491,6 +501,9 @@ func TestTxNotifierFutureSpendDispatch(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to connect block: %v", err)
|
t.Fatalf("unable to connect block: %v", err)
|
||||||
}
|
}
|
||||||
|
if err := n.NotifyHeight(12); err != nil {
|
||||||
|
t.Fatalf("unable to dispatch notifications: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-ntfn.Event.Spend:
|
case <-ntfn.Event.Spend:
|
||||||
@ -570,6 +583,9 @@ func TestTxNotifierHistoricalSpendDispatch(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to connect block: %v", err)
|
t.Fatalf("unable to connect block: %v", err)
|
||||||
}
|
}
|
||||||
|
if err := n.NotifyHeight(startingHeight + 1); err != nil {
|
||||||
|
t.Fatalf("unable to dispatch notifications: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-ntfn.Event.Spend:
|
case <-ntfn.Event.Spend:
|
||||||
@ -931,6 +947,9 @@ func TestTxNotifierCancelSpend(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to connect block: %v", err)
|
t.Fatalf("unable to connect block: %v", err)
|
||||||
}
|
}
|
||||||
|
if err := n.NotifyHeight(startingHeight + 1); err != nil {
|
||||||
|
t.Fatalf("unable to dispatch notifications: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
// The first request should still be active, so we should receive a
|
// The first request should still be active, so we should receive a
|
||||||
// spend notification with the correct spending details.
|
// spend notification with the correct spending details.
|
||||||
@ -1024,22 +1043,28 @@ func TestTxNotifierConfReorg(t *testing.T) {
|
|||||||
block1 := btcutil.NewBlock(&wire.MsgBlock{
|
block1 := btcutil.NewBlock(&wire.MsgBlock{
|
||||||
Transactions: []*wire.MsgTx{&tx1},
|
Transactions: []*wire.MsgTx{&tx1},
|
||||||
})
|
})
|
||||||
err := n.ConnectTip(nil, 8, block1.Transactions())
|
if err := n.ConnectTip(nil, 8, block1.Transactions()); err != nil {
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Failed to connect block: %v", err)
|
t.Fatalf("Failed to connect block: %v", err)
|
||||||
}
|
}
|
||||||
err = n.ConnectTip(nil, 9, nil)
|
if err := n.NotifyHeight(8); err != nil {
|
||||||
if err != nil {
|
t.Fatalf("unable to dispatch notifications: %v", err)
|
||||||
|
}
|
||||||
|
if err := n.ConnectTip(nil, 9, nil); err != nil {
|
||||||
t.Fatalf("Failed to connect block: %v", err)
|
t.Fatalf("Failed to connect block: %v", err)
|
||||||
}
|
}
|
||||||
|
if err := n.NotifyHeight(9); err != nil {
|
||||||
|
t.Fatalf("unable to dispatch notifications: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
block2 := btcutil.NewBlock(&wire.MsgBlock{
|
block2 := btcutil.NewBlock(&wire.MsgBlock{
|
||||||
Transactions: []*wire.MsgTx{&tx2, &tx3},
|
Transactions: []*wire.MsgTx{&tx2, &tx3},
|
||||||
})
|
})
|
||||||
err = n.ConnectTip(nil, 10, block2.Transactions())
|
if err := n.ConnectTip(nil, 10, block2.Transactions()); err != nil {
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Failed to connect block: %v", err)
|
t.Fatalf("Failed to connect block: %v", err)
|
||||||
}
|
}
|
||||||
|
if err := n.NotifyHeight(10); err != nil {
|
||||||
|
t.Fatalf("unable to dispatch notifications: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
// We should receive two updates for tx1 since it requires two
|
// We should receive two updates for tx1 since it requires two
|
||||||
// confirmations and it has already met them.
|
// confirmations and it has already met them.
|
||||||
@ -1093,20 +1118,23 @@ func TestTxNotifierConfReorg(t *testing.T) {
|
|||||||
|
|
||||||
// The block that included tx2 and tx3 is disconnected and two next
|
// The block that included tx2 and tx3 is disconnected and two next
|
||||||
// blocks without them are connected.
|
// blocks without them are connected.
|
||||||
err = n.DisconnectTip(10)
|
if err := n.DisconnectTip(10); err != nil {
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Failed to connect block: %v", err)
|
t.Fatalf("Failed to connect block: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = n.ConnectTip(nil, 10, nil)
|
if err := n.ConnectTip(nil, 10, nil); err != nil {
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Failed to connect block: %v", err)
|
t.Fatalf("Failed to connect block: %v", err)
|
||||||
}
|
}
|
||||||
|
if err := n.NotifyHeight(10); err != nil {
|
||||||
|
t.Fatalf("unable to dispatch notifications: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
err = n.ConnectTip(nil, 11, nil)
|
if err := n.ConnectTip(nil, 11, nil); err != nil {
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Failed to connect block: %v", err)
|
t.Fatalf("Failed to connect block: %v", err)
|
||||||
}
|
}
|
||||||
|
if err := n.NotifyHeight(11); err != nil {
|
||||||
|
t.Fatalf("unable to dispatch notifications: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case reorgDepth := <-ntfn2.Event.NegativeConf:
|
case reorgDepth := <-ntfn2.Event.NegativeConf:
|
||||||
@ -1151,15 +1179,21 @@ func TestTxNotifierConfReorg(t *testing.T) {
|
|||||||
})
|
})
|
||||||
block4 := btcutil.NewBlock(&wire.MsgBlock{})
|
block4 := btcutil.NewBlock(&wire.MsgBlock{})
|
||||||
|
|
||||||
err = n.ConnectTip(block3.Hash(), 12, block3.Transactions())
|
err := n.ConnectTip(block3.Hash(), 12, block3.Transactions())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to connect block: %v", err)
|
t.Fatalf("Failed to connect block: %v", err)
|
||||||
}
|
}
|
||||||
|
if err := n.NotifyHeight(12); err != nil {
|
||||||
|
t.Fatalf("unable to dispatch notifications: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
err = n.ConnectTip(block4.Hash(), 13, block4.Transactions())
|
err = n.ConnectTip(block4.Hash(), 13, block4.Transactions())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to connect block: %v", err)
|
t.Fatalf("Failed to connect block: %v", err)
|
||||||
}
|
}
|
||||||
|
if err := n.NotifyHeight(13); err != nil {
|
||||||
|
t.Fatalf("unable to dispatch notifications: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
// We should only receive one update for tx2 since it only requires
|
// We should only receive one update for tx2 since it only requires
|
||||||
// one confirmation and it already met it.
|
// one confirmation and it already met it.
|
||||||
@ -1293,12 +1327,13 @@ func TestTxNotifierSpendReorg(t *testing.T) {
|
|||||||
block1 := btcutil.NewBlock(&wire.MsgBlock{
|
block1 := btcutil.NewBlock(&wire.MsgBlock{
|
||||||
Transactions: []*wire.MsgTx{spendTx1},
|
Transactions: []*wire.MsgTx{spendTx1},
|
||||||
})
|
})
|
||||||
err := n.ConnectTip(
|
err := n.ConnectTip(block1.Hash(), startingHeight+1, block1.Transactions())
|
||||||
block1.Hash(), startingHeight+1, block1.Transactions(),
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to connect block: %v", err)
|
t.Fatalf("unable to connect block: %v", err)
|
||||||
}
|
}
|
||||||
|
if err := n.NotifyHeight(startingHeight + 1); err != nil {
|
||||||
|
t.Fatalf("unable to dispatch notifications: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
// We should receive a spend notification for the first outpoint with
|
// We should receive a spend notification for the first outpoint with
|
||||||
// its correct spending details.
|
// its correct spending details.
|
||||||
@ -1322,12 +1357,13 @@ func TestTxNotifierSpendReorg(t *testing.T) {
|
|||||||
block2 := btcutil.NewBlock(&wire.MsgBlock{
|
block2 := btcutil.NewBlock(&wire.MsgBlock{
|
||||||
Transactions: []*wire.MsgTx{spendTx2},
|
Transactions: []*wire.MsgTx{spendTx2},
|
||||||
})
|
})
|
||||||
err = n.ConnectTip(
|
err = n.ConnectTip(block2.Hash(), startingHeight+2, block2.Transactions())
|
||||||
block2.Hash(), startingHeight+2, block2.Transactions(),
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to connect block: %v", err)
|
t.Fatalf("unable to connect block: %v", err)
|
||||||
}
|
}
|
||||||
|
if err := n.NotifyHeight(startingHeight + 2); err != nil {
|
||||||
|
t.Fatalf("unable to dispatch notifications: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
// We should not receive another spend notification for the first
|
// We should not receive another spend notification for the first
|
||||||
// outpoint.
|
// outpoint.
|
||||||
@ -1381,6 +1417,9 @@ func TestTxNotifierSpendReorg(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to disconnect block: %v", err)
|
t.Fatalf("unable to disconnect block: %v", err)
|
||||||
}
|
}
|
||||||
|
if err := n.NotifyHeight(startingHeight + 2); err != nil {
|
||||||
|
t.Fatalf("unable to dispatch notifications: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
// We shouldn't receive notifications for either of the outpoints.
|
// We shouldn't receive notifications for either of the outpoints.
|
||||||
select {
|
select {
|
||||||
@ -1403,6 +1442,9 @@ func TestTxNotifierSpendReorg(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to connect block: %v", err)
|
t.Fatalf("unable to connect block: %v", err)
|
||||||
}
|
}
|
||||||
|
if err := n.NotifyHeight(startingHeight + 3); err != nil {
|
||||||
|
t.Fatalf("unable to dispatch notifications: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
// We should now receive a spend notification once again for the second
|
// We should now receive a spend notification once again for the second
|
||||||
// outpoint containing the new spend details.
|
// outpoint containing the new spend details.
|
||||||
@ -1489,12 +1531,13 @@ func TestTxNotifierConfirmHintCache(t *testing.T) {
|
|||||||
Transactions: []*wire.MsgTx{&txDummy},
|
Transactions: []*wire.MsgTx{&txDummy},
|
||||||
})
|
})
|
||||||
|
|
||||||
err = n.ConnectTip(
|
err = n.ConnectTip(block1.Hash(), txDummyHeight, block1.Transactions())
|
||||||
block1.Hash(), txDummyHeight, block1.Transactions(),
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to connect block: %v", err)
|
t.Fatalf("Failed to connect block: %v", err)
|
||||||
}
|
}
|
||||||
|
if err := n.NotifyHeight(txDummyHeight); err != nil {
|
||||||
|
t.Fatalf("unable to dispatch notifications: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
// Since UpdateConfDetails has not been called for either transaction,
|
// Since UpdateConfDetails has not been called for either transaction,
|
||||||
// the height hints should remain unchanged. This simulates blocks
|
// the height hints should remain unchanged. This simulates blocks
|
||||||
@ -1529,12 +1572,13 @@ func TestTxNotifierConfirmHintCache(t *testing.T) {
|
|||||||
Transactions: []*wire.MsgTx{&tx1},
|
Transactions: []*wire.MsgTx{&tx1},
|
||||||
})
|
})
|
||||||
|
|
||||||
err = n.ConnectTip(
|
err = n.ConnectTip(block2.Hash(), tx1Height, block2.Transactions())
|
||||||
block2.Hash(), tx1Height, block2.Transactions(),
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to connect block: %v", err)
|
t.Fatalf("Failed to connect block: %v", err)
|
||||||
}
|
}
|
||||||
|
if err := n.NotifyHeight(tx1Height); err != nil {
|
||||||
|
t.Fatalf("unable to dispatch notifications: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
// Now that both notifications are waiting at tip for confirmations,
|
// Now that both notifications are waiting at tip for confirmations,
|
||||||
// they should have their height hints updated to the latest block
|
// they should have their height hints updated to the latest block
|
||||||
@ -1563,12 +1607,13 @@ func TestTxNotifierConfirmHintCache(t *testing.T) {
|
|||||||
Transactions: []*wire.MsgTx{&tx2},
|
Transactions: []*wire.MsgTx{&tx2},
|
||||||
})
|
})
|
||||||
|
|
||||||
err = n.ConnectTip(
|
err = n.ConnectTip(block3.Hash(), tx2Height, block3.Transactions())
|
||||||
block3.Hash(), tx2Height, block3.Transactions(),
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to connect block: %v", err)
|
t.Fatalf("Failed to connect block: %v", err)
|
||||||
}
|
}
|
||||||
|
if err := n.NotifyHeight(tx2Height); err != nil {
|
||||||
|
t.Fatalf("unable to dispatch notifications: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
// The height hint for the first transaction should remain the same.
|
// The height hint for the first transaction should remain the same.
|
||||||
hint, err = hintCache.QueryConfirmHint(tx1Hash)
|
hint, err = hintCache.QueryConfirmHint(tx1Hash)
|
||||||
@ -1682,6 +1727,9 @@ func TestTxNotifierSpendHintCache(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to connect block: %v", err)
|
t.Fatalf("unable to connect block: %v", err)
|
||||||
}
|
}
|
||||||
|
if err := n.NotifyHeight(dummyHeight); err != nil {
|
||||||
|
t.Fatalf("unable to dispatch notifications: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
// Since we haven't called UpdateSpendDetails on any of the test
|
// Since we haven't called UpdateSpendDetails on any of the test
|
||||||
// outpoints, this implies that there is a still a pending historical
|
// outpoints, this implies that there is a still a pending historical
|
||||||
@ -1720,6 +1768,9 @@ func TestTxNotifierSpendHintCache(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to connect block: %v", err)
|
t.Fatalf("unable to connect block: %v", err)
|
||||||
}
|
}
|
||||||
|
if err := n.NotifyHeight(op1Height); err != nil {
|
||||||
|
t.Fatalf("unable to dispatch notifications: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
// Both outpoints should have their spend hints reflect the height of
|
// Both outpoints should have their spend hints reflect the height of
|
||||||
// the new block being connected due to the first outpoint being spent
|
// the new block being connected due to the first outpoint being spent
|
||||||
@ -1749,6 +1800,9 @@ func TestTxNotifierSpendHintCache(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to connect block: %v", err)
|
t.Fatalf("unable to connect block: %v", err)
|
||||||
}
|
}
|
||||||
|
if err := n.NotifyHeight(op2Height); err != nil {
|
||||||
|
t.Fatalf("unable to dispatch notifications: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
// Only the second outpoint should have its spend hint updated due to
|
// Only the second outpoint should have its spend hint updated due to
|
||||||
// being spent within the new block. The first outpoint's spend hint
|
// being spent within the new block. The first outpoint's spend hint
|
||||||
|
@ -181,8 +181,8 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
|
|||||||
cleanUp func()
|
cleanUp func()
|
||||||
)
|
)
|
||||||
|
|
||||||
// Initialize disabled height hint cache within the chain directory.
|
// Initialize the height hint cache within the chain directory.
|
||||||
hintCache, err := chainntnfs.NewHeightHintCache(chanDB, true)
|
hintCache, err := chainntnfs.NewHeightHintCache(chanDB)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("unable to initialize height hint "+
|
return nil, nil, fmt.Errorf("unable to initialize height hint "+
|
||||||
"cache: %v", err)
|
"cache: %v", err)
|
||||||
|
@ -2153,7 +2153,7 @@ func TestLightningWallet(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to create db: %v", err)
|
t.Fatalf("unable to create db: %v", err)
|
||||||
}
|
}
|
||||||
hintCache, err := chainntnfs.NewHeightHintCache(db, true)
|
hintCache, err := chainntnfs.NewHeightHintCache(db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to create height hint cache: %v", err)
|
t.Fatalf("unable to create height hint cache: %v", err)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user