Commit Graph

103 Commits

Author SHA1 Message Date
Wilmer Paulino
7239e04696
chainntnfs: initialize TxNotifier with new ReorgSafetyLimit 2019-01-11 16:58:15 -08:00
Olaoluwa Osuntokun
28eb8474f4
chainntnfs: modify all historical rescans to scan backwards
In this commit, we modify all existing historical rescans for
ChainNotifier backends to scan backwards rather than forwards. If we
know that a transaction has been confirmed, or outpoint spent, the it's
likely that the event has recently transpired assuming we've been
offline for a short period of time. Therefore, if we scan backwards
rather than forwards, then we can save potentially hundreds or thousands
of block fetches if the event recently happened close to the tip of the
chain.

We bound this search at the genesis block, to ensure we don't underflow
the uint32 used throughout the package in the main loop.
2018-11-24 15:50:12 -06:00
Wilmer Paulino
e402a4e146
chainntnfs: dispatch conf/spend notifications after blocks
In this commit, we alter the different ChainNotifier implementations to
dispatch confirmation and spend notifications after blocks. We do this
to ensure the external consistency of our registered clients.
2018-10-31 09:20:22 -07:00
Wilmer Paulino
9a025867d0
Revert "chainntnfs/btcdnotify: disable height hint cache in testing"
This reverts commit 98e7c968d4bf5900a5d7be7f557eab8f623633c0.
2018-10-31 09:20:22 -07:00
Wilmer Paulino
74139c9a3f
chainntnfs/btcdnotify: remove old spend notification handling logic
In this commit, we remove the old spend notification logic within the
BtcdNotifier as it's been phased out by the TxNotifier.
2018-10-30 17:59:31 -07:00
Wilmer Paulino
88edd320d5
chainntnfs/btcdnotify: handle spend notification registration w/ TxNotifier
In this commit, we modify the logic within RegisterSpendNtfn for the
BtcdNotifier to account for the recent changes made to the TxNotifier.
Since it is now able to handle spend notification registration and
dispatch, we can bypass all the current logic within the
BtcdNotifier and interact directly with the TxNotifier instead.

The most notable change is that now we'll only attempt a historical
rescan if the TxNotifier tells us so.
2018-10-30 17:59:31 -07:00
Wilmer Paulino
f65401b439
chainntnfs/txnotifier: rename Register -> RegisterConf 2018-10-30 17:59:31 -07:00
Wilmer Paulino
82f6fd7a91
chainntnfs: rename TxConfNotifier -> TxNotifier 2018-10-30 17:59:31 -07:00
Conner Fromknecht
6cd0f867ad
chainntnfs/btcd: use HistoricalConfDispatch in ntfn registry 2018-10-26 18:32:30 -07:00
Conner Fromknecht
cf7700e6cb
chainntnfs/bitcoind+btcd+neutrino: let tcn query for height hint 2018-10-26 18:32:29 -07:00
Conner Fromknecht
a1756b0b1b
chainntnfs/bitcoind+btcd+neutrino: pass nil conf details 2018-10-26 18:32:28 -07:00
Johan T. Halseth
dbf9b4ea4c
chainntnfs+queue: move ConcurrentQueue to own package 'queue' 2018-10-18 12:38:10 -07:00
Conner Fromknecht
3403794e81
chainntnfs: switch debug tag to dev
This avoids collisions with the logging level tags
2018-10-05 12:59:34 +09:00
Conner Fromknecht
e498a837a3
chainntnfs/btcd: commit spend hints before notifying 2018-10-02 01:09:26 -07:00
maurycy
ac24b12bf2
multi: fix various typos in comments 2018-09-07 06:51:49 +02:00
Conner Fromknecht
98e7c968d4
chainntnfs/btcdnotify: disable height hint cache in testing 2018-08-26 15:34:20 -07:00
Johan T. Halseth
01d8953737
chainntnfs/btcd: fallback to scan manually only in case of err != nil 2018-08-24 14:46:20 +02:00
Johan T. Halseth
31dc387e0f
chainntnfs/btcd+bitcoind tests: use common TxConfStatus 2018-08-24 14:46:20 +02:00
Johan T. Halseth
79b2ee7da5
chainntnfs/btcd+bitcoind: use common TxConfStatus 2018-08-24 14:46:20 +02:00
Johan T. Halseth
4a60887974
chainntnfs/btcd: remove unnecessary check for tx==nil 2018-08-24 14:46:19 +02:00
Conner Fromknecht
ecc91305ac
chainntnfs/btcdnotify: initialize with height hint cache 2018-08-24 04:05:46 -07:00
Wilmer Paulino
cb688de7ad
chainntnfs: guard test chain notifier under debug flag 2018-08-24 03:36:25 -07:00
Wilmer Paulino
7895f01e2e
chainntnfs: ensure proper fallback to scanning tx manually
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.
2018-08-24 03:36:24 -07:00
Wilmer Paulino
94beabf34b
chainntnfs: cache spend hints within the different chain notifiers
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.
2018-08-21 12:55:53 -04:00
Wilmer Paulino
7e872566c4
chainntnfs: query the hint cache before registering a conf ntfn
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.
2018-08-21 12:55:52 -04:00
Wilmer Paulino
30fd219b1c
chainntnfs: add height hint caches to chain notifiers 2018-08-21 12:55:51 -04:00
Valentine Wallace
b3a5b3b576
chainntnfs: add ChainNotifier test interface for test methods
TestChainNotifier wraps the ChainNotifier interface to allow adding additional testing methods with access to private fields in the notifiers. These testing methods are only compiled when the build tag "debug" is set. UnsafeStart allows starting a notifier with a specified best block.

UnsafeStart is useful for the purpose of testing cases where a notifier's best block is out of date when it receives a new block.
2018-08-11 22:45:03 -07:00
Valentine Wallace
79cbea1c9c
chainntnfs: enable notifiers to catch up on missed blocks
This resolves the situation where a notifier's chain backend skips a series of blocks, causing the notifier to need to dispatch historical block notifications to clients.

Additionally, if the current notifier's best block has been reorged out, this logic enables the notifier to rewind to the common ancestor between the current chain and the outdated best block and dispatches notifications from the ancestor.
2018-08-10 01:08:58 -07:00
Valentine Wallace
3df5b26699
chainntnfs: notify clients after block connect has succeeded
This prevents the situation where we notify clients about a newly connected block, and then the block connection itself fails. We also want to set our best block in between connecting the block and notifying clients, in case a client makes queries about the new block they have received.
2018-08-10 01:08:58 -07:00
Valentine Wallace
cbf1799c40
chainntnfs: rewind chain on missed disconnected blocks
If the chain backend misses telling the notifier about a series of disconnected blocks, the notifier is now able to disconnect the tip to its new best block.
2018-08-10 01:08:57 -07:00
Valentine Wallace
a5e1cf9c97
chainntnfs: dispatch historical block ntfns to clients
If a client passes in their best known block when registering for block notifications, check to see if it's behind our best block. If so, dispatch the missed block notifications to the client.

This is necessary because clients that persist their best known block can miss new blocks while registering for notifications.
2018-08-10 01:08:57 -07:00
Valentine Wallace
d4cf271526
chainntnfs: track best block in btcd and bitcoind 2018-08-10 01:08:57 -07:00
Valentine Wallace
71a81f59a9
chainntnfs: allow clients to pass in best block
Clients can optionally pass their best block known into RegisterBlockEpochNtfn. This enables the notifiers to catch up clients on blocks they may have missed.
2018-08-10 01:08:54 -07:00
Conner Fromknecht
1ded697e8d
multi: sort import paths with gofmt 2018-08-02 18:20:49 -07:00
Olaoluwa Osuntokun
6781b17056
chainntnfs: update bitcoind and btcd backends to match new spend ntfn API 2018-07-31 21:28:53 -07:00
Olaoluwa Osuntokun
e93149e576
chainntnfs/btcdnotify: update RegisterConfirmationsNtfn to take pkScript 2018-07-31 21:28:49 -07:00
Wilmer Paulino
12816a910d chainntnfs: make historical confirmation rescans async 2018-07-31 18:23:25 -07:00
Wilmer Paulino
c43506dee9 chainntnfs: add unique ID field to track conf ntfns within notifier 2018-07-31 18:23:25 -07:00
Johan T. Halseth
3808105dcd
chainntnfs/btcdnotify: remove all mempool spend clients 2018-07-22 23:09:08 +02:00
Johan T. Halseth
44d7b84df0
chainntnfs: remove mempool option from RegisterSpendNtfn 2018-07-22 23:09:08 +02:00
Olaoluwa Osuntokun
274687471a
chainntnfs/btcdnotify: switch to async rescan call for historical spend ntfns
In this commit, we modify the way to handle historical spend dispatches
to ensure that we don't block the client for very old rescans. Rather
than blocking and waiting for the rescan to finish (which may take
minutes in the worst case), we'll now instead launch a goroutine to
handle the async response of the rescan.
2018-07-18 01:31:49 -07:00
Olaoluwa Osuntokun
6f60f139f4 multi: switch over import paths from roasbeef/* to btcsuite/* 2018-07-13 17:05:39 -07:00
Wilmer Paulino
13fb866574
chainntnfs: remove txindex requirement when registering notfications
Before this commit, we relied on the need of full nodes to enable the
transaction index. This allowed us to fetch historical details about
transactions in order to register and dispatch confirmation and spend
notifications.

This commit allows us to drop that requirement by providing a fallback
method to use when the transaction index is not enabled. This fallback
method relies on manually scanning blocks for the transactions
requested, starting from the earliest height the transactions could have
been included in, to the current height in the chain.
2018-04-17 14:59:51 -04:00
Johan T. Halseth
5d6dd90d18
chainntnfs/btcdnotify: correctly notify on confirmed rescan spends
This commit fixes a recently introduced bug in the btcdnotifier, where
we would skip all spend clients waiting for a confirmed spend in
txUpdates. The regular case where a spend is included in a new block was
correctly handled in onBlockConnected, but the txUpdates queue is also
used for confirmed spends during rescans, which we would miss. This
commit fixes that by checking if the tx update is confirmed or
unconfirmed, and acts accordingly.
2018-04-16 20:09:08 +02:00
Olaoluwa Osuntokun
86ad6d318e
Merge pull request #889 from wpaulino/chainnotifier-updates
chainntnfs: add incremental update notifications within ChainNotifier
2018-04-12 19:21:26 -07:00
Wilmer Paulino
486694a84e
chainntnfs: add Updates channel field to ConfirmationEvent
In this commit, we add a new Updates channel to our ConfirmationEvent
struct. This channel will be used to deliver updates to a subscriber of
a confirmation notification. Updates will be delivered at every
incremental height of the chain with the number of confirmations
remaining for the transaction to be considered confirmed by the
subscriber.
2018-04-06 00:30:19 -04:00
Johan T. Halseth
cc17bc1636
chainntnfs/btcd: add logic for mempool argument to RegisterSpendNtfn
This commit adds a boolean to RegisterSpendNtfn, giving the caller the
option to only register for notifications on confirmed spends. This is
implemented for the btcd backend using logic similar to what is in used
for Neutrino, paving the way for later unifying them.
2018-04-03 11:24:07 +02:00
Johan T. Halseth
b08fc05390
chainntnfs/btcd: move NotifySpent to after recording the outpoint
This commit moves the call to the btcd backend to start watching an
outpoint for spentness to after we have recorded the outpoint in our
list of clients. This is done to avoid a race that could occur if btcd
quicly sent a spend notification before we had been able to record it in
our map, essentially losing it.
2018-03-28 10:21:08 +02:00
Olaoluwa Osuntokun
9c18c3d9a4
chainntnfs: ensure all block epoch notifications are sent *in order*
In this commit, we fix a lingering bug related to the way that we
deliver block epoch notifications to end users. Before this commit, we
would launch a new goroutine for *each block*. This was done in order
to ensure that the notification dispatch wouldn’t block the main
goroutine that was dispatching the notifications. This method archived
the goal, but had a nasty side effect that the goroutines could be
re-ordered during scheduling, meaning that in the case of fast
successive blocks, then notifications would be delivered out of order.
Receiving out of order notifications is either disallowed, or can cause
sub-systems that rely on these notifications to get into weird states.

In order to fix this issue, we’ll no longer launch a new goroutine to
deliver each notification to an awaiting client. Instead, each client
will now gain a concurrent in-order queue for notification delivery.
Due to the internal design of chainntnfs.ConcurrentQueue, the caller
should never block, yet the receivers will receive notifications in
order. This change solves the re-ordering issue and also minimizes the
number of goroutines that we’ll create in order to deliver block epoch
notifications.
2018-02-09 16:13:28 -08:00
Olaoluwa Osuntokun
bf6001074c
chainntnfs: fix spend notification registration race condition
In this commit, we fix a race condition related to the way we attempt
to query to see if an outpoint has already been spent by the time it’s
registered within the ChainNotifier. If the transaction creating the
outpoint hasn’t made it into the mempool by the time we execute the
GetTxOut call, then we’ll attempt to query for the transaction itself.
In this case, if we query for the transaction, then the block hash
field will be empty as it hasn’t yet made it into a block. Under the
previous logic, we’d then attempt to force a rescan. This is an issue
as the forced rescan will fail since it’ll try to fetch the block hash
of all zeroes.

In this commit, we fix this issue by only entering this “fallback to
rescan” logic iff, the transaction has actually been mined.
2018-01-28 14:48:56 -08:00