Initial version of the checkpoint pruner:
Similar to the existing objects pruner (i.e., tails checkpoints from the
past epochs and removes relevant data).
Notes:
* current approach employs rocksdb's `delete_range` API. Point-delete
tombstones have a negative performance impact on reads. It may still
suffer from the same issue where deleted data occupies space in SST
files, so alternative solutions like FIFO compaction style should be
considered in the future
* each pruning batch affects both the perpetual DB and the checkpoint
DB. We can't have an atomic batch between those two, so ordering is
important. The perpetual DB batch must be committed first. Its changes
are idempotent. Because of this, the pruning watermark is stored in the
checkpoint DB
* the checkpoint pruner is blocked by the objects pruner watermark. It's
necessary because once the checkpoint is gone, there's no way to delete
the corresponding objects
* objects and checkpoints pruning are two separate routines. That's
because a node can have different pruning policies for them, and objects
pruning is not idempotent in general. In the future, a new Universal
pruning mode can be added that aligns the two if pruning settings are
similar. That should help with resource consumption on the node so that
the same data won't be read twice during two different time windows