-
Notifications
You must be signed in to change notification settings - Fork 282
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fullnode interactive rescan. #856
Conversation
There is a bug in The interactive rescan allows bigger gaps between Now when calling |
c71aee1
to
a9859f6
Compare
tx: Add .test method that does not update the filter.
0 is falsy, so this would fail for the value of 0.
a9859f6
to
1b1740c
Compare
If the client closes before the socket.call, next call would never resolve nor reject and locker would never unlock.
1b1740c
to
140265e
Compare
Chain "interactive scan"
Motivation
The chain already has scan capabilities, which are used by the wallet
(and separate indexers) to catch up to the tip or to rescan the state of the
blocks for missing data.
But unfortunately, it is not enough for the wallet. The rescanned block can
update the filter, and that means we need to check the same block with the
updated filter. Any indexer using filters will have the same issue. The wallet
is just an indexer with a filter.
Goals
rescan interactive Chain API
Chain API only exposes single method that is doing all the processing:
scanInteractive(start, filter, iter)
start
is Block Hash or Number where to start the scan.filter
initial BloomFilter, if it's null than block will return all TXs.iter(chainEntry, txs): scanAction
- this is the callback for per blockiteration as well as the main way to control the flow of the rescan.
iter
callback returnsscanAction
object which hastype
and controls theflow of the scan. Action object takes form:
{ type: ACTION_TYPE, ...additional_fields }
Actions:
NEXT
- move on to the next block. This is the default and only behaviournon-interactive rescan. (
{ type: scanActions.NEXT }
)ABORT
- abort the scan process. ({ type: scanAction.ABORT }
)REPEAT
- Repeat the last block with the same filter. Note, that if filterwas passed as a reference and filter was updated, next block scan will use
updated filter. (
{ type: scanAction.REPEAT }
)REPEAT_SET
- Repeat the last block but set new filter. This replaces lastfilter with new one and repeats scan of the block.
(
{ type: scanAction.REPEAT_SET, filter: BloomFilter }
)REPEAT_ADD
- Add new entries to the filter before repeating the scan ofthe same block. Useful if you don't have reference to the original filter
that was passed (e.g. in HTTP). Chunks will get added to the filter and then
will rescan the same block.
(
{ type: scanAction.REPEAT_ADD, chunks: Buffer[] }
)"ABORT", "incorrect action", and "internal error" will all abort the rescan
with the appropriate error message. For example, if a reorganization happens on
the chain we are currently on and some other chain becomes the main, it will
abort the scan and throw an error.
Differences between existing scan and interactive scan
In case you are using the behavior as the normal scan - using only
NEXT
,there's one big difference. The existing rescan stops the chain from progressing
until the rescan is finished, which in turn avoids reorganizations and
invalidation of the scan. That is not the case with the interactive scan.
It does not stop the chain from progressing, meaning it can end up on an
alternative chain at some point. In that case, the rescan will abort. In turn, it
allows multiple rescans to be active at once.
HTTP API
The HTTP API for the interactive rescan allows only 1 rescan per client (this
can be changed if necessary). However, the server currently does not have any
limits on how many parallel rescans can be executed, which is different from
the normal rescan that blocks the whole chain. The Rescan API uses websockets for
communication, so the websocket connection must be opened first.
NodeClient
now has new methodrescanInteractive(start, filter)
.filter
needs to be either encoded BloomFilter or
null
. Iffilter
is not providedclient.filter
which was set previously usingset filter
will be used.If you want ALL TXs and you have previously used
set filter
with that client,you will need to
reset filter
first.Server expects clients to have the
hooks
necessary for the rescan processdescribed below:
rescanInteractive
- starts the rescan process.block rescan interactive
with args:(rawEntry, rawTXs)
and returnsencoded scanAction
.filter
inREPEAT_SET
action needs to be encodedBloom filter.
block rescan interactive abort
called with args(message)
.Note, if you are socket.filter (set using
set filter
),REPEAT_ADD
will updatethe socket.filter itself.
Other changes