This commit removes shadowing of the currentHeight
variable when registering for neutrino spend
notifications. Currently, a locally scoped variable
is used when determining if the backend is fully
synced before attempting to call GetUtxo, which
means that the variable won't be updated after
breaking out of the loop. As a result, this could
cause us to scan unnecessarily if the backend is
catching up, e.g. after being offline for some time.
After joining the two forked chains, it is necessary to ensure they both agree on the same best hash before proceeding to UnsafeStart the notifier.
This is because when the BitcoindClient starts, it retrieves its best known block then calls GetBlockHeaderVerbose on the hash of the retrieved block. This block could be a reorged block if JoinNodes has not completed sync. If it is the case that the best block retrieved has been reorged out of the chain, GetBlockHeaderVerbose errors because bitcoind sets the number of confirmations to -1 on reorged blocks, and the btcd rpc client panics when parsing a block whose number of confirmations is negative.
This parsing error is expected to be fixed, and as a more permanent solution chain backends should ensure that the `best block` they retrieve during startup has not been reorged out of the chain.
In this commit, we address a bug where it's possible that we still
attempt to manually scan for a transaction to determine whether it's
been included in the chain even after successfully checking the txindex
and not finding it there. Now, we'll short-circuit this process by
exiting early if the txindex lookup was successful but the transaction
in question was not found. Otherwise, we'll fall back to the manual
scan.
In this commit, we extract some of the helper test variables and
functions into their own file and guard them under a build flag. This is
needed as some unit tests will be introduced in a future commit where
most of the same functions within the interface tests are reused. In
order to prevent these variables and functions from being exportable, we
guard them by the "debug" build tag.
rescanning
In this commit, we modify the rescan options Neutrino uses when
performing a rescan for historical chain events to disable disconnected
block notifications. This is needed as the Neutrino backend will mutate
its internal state while rewinding, which causes disconnected block
notifications to be sent. Since the notifier acts upon these
notifications, they would cause it to also rewind unnecessarily.
In this commit, we extend the different ChainNotifier implementations to
cache height hints for our spend events. Each outpoint we've requested a
spend notification for will have its initial height hint cached. We then
increment this height hint at every new block for unspent outpoints.
This allows us to retrieve the *exact* height at which the outpoint has
been spent. By doing this, we optimize the different ChainNotifier
implementations since they will no longer have to rescan forward (and
possibly fetch blocks in the neutrino/pruned node case) from the initial
height hint.
In this commit, we alter the different chain notifiers to query their
height hint cache before registering a confimation notification. We do
this as it's possible that the cache has a higher height hint, which
can potentially reduce the amount of blocked fetched when attempting
historical dispatches.
In this commit, we extend our TxConfNotifier to cache height hints for
our confirmation events. Each transaction we've requested a confirmation
notification for will have its initial height hint cached. We increment
this height hint at every new block for unconfirmed transactions. This
allows us to retrieve the *exact* height at which the transaction has
been included in a block. By doing this, we optimize the different
ChainNotifier implementations since they will no longer have to scan
forward (and possibly fetch blocks in the neutrino/pruned node case)
from the initial height hint looking for the confirmation.
In this commit, we introduce two new interfaces: SpendHintCache and
ConfirmHintCache for a height hint cache. The SpendHintCache is
responsible for maintaining the earliest height at which an outpoint
could have been spent within the chain, while the ConfirmHintCache is
responsible for maintaining the earliest height at which a transaction
confirms within the chain. We also add an implementation of these
interfaces with a single struct HeightHintCache, backed by a channeldb
instance, which will cary the duties of the interfaces above.