Our Compact Block Filters implementation currently have several problems:
- It is slow and brittle, not reliable at all.
- It stores all filters in a range, when most clients actually only keeps the last
N filters and all headers.
- It pours most of the filters logic inside
wire, which is a domain violation.
- It forces users to re-implement the rescan logic every time
For that reason, we should have a new approach, that:
- Prefer keeping headers, not full filters (modulo a small cache for recent filters). This is usually how other implementations does it, and saves disk space.
- Don't make
floresta-wire coordinate anything. It is a wire library, it shouldn't know about filter's business logic.
- Encapsulate all rescan logic under a common interface and avoid code repetition
The approach I've came up with (see #1079), introduces a new filters manager that takes care of everything. This will be a separated service that runs on a loop and responds to requests made through a handle. It uses NodeInterface to gather data such as blocks and filters.
Rescanning is an async process, as it might take a considerable amount of time to run. For that reason, I've implemented a polling-based system to fetch rescan blocks as we find them. Since a wallet might have too many transactions, that could
DoS our node in case we get all those blocks in-memory. To solve that, there's a pagination system where you need to consume available blocks before we request more. Once we finish with all blocks, the rescan is over.
This task is meant to run from the get-go, and will start downloading filter right after headers-sync is finished, so our node is "usable" in a few minutes. Even if IBD takes hours.
Roadmap
Some things will be required during this project, I'll break them into a few PRs to help with review
Some of these might be a follow up to reduce complexity here.
Our Compact Block Filters implementation currently have several problems:
Nfilters and all headers.wire, which is a domain violation.For that reason, we should have a new approach, that:
floresta-wirecoordinate anything. It is a wire library, it shouldn't know about filter's business logic.The approach I've came up with (see #1079), introduces a new filters manager that takes care of everything. This will be a separated service that runs on a loop and responds to requests made through a handle. It uses
NodeInterfaceto gather data such as blocks and filters.Rescanning is an async process, as it might take a considerable amount of time to run. For that reason, I've implemented a polling-based system to fetch rescan blocks as we find them. Since a wallet might have too many transactions, that could
DoS our node in case we get all those blocks in-memory. To solve that, there's a pagination system where you need to consume available blocks before we request more. Once we finish with all blocks, the rescan is over.
This task is meant to run from the get-go, and will start downloading filter right after headers-sync is finished, so our node is "usable" in a few minutes. Even if IBD takes hours.
Roadmap
Some things will be required during this project, I'll break them into a few PRs to help with review
node_handle(feat(node): Add GetCFHeaders to the node handle #1088)node_handletry_and_*to common, so we can use them here as well (refactor: movetry_and_*tocommon#1096)chain(feat(chain)!: Use a more granular state machine for IBD #1095)Some of these might be a follow up to reduce complexity here.