kernel: Add functions to read block from disk to C header

This adds functions for reading a block from disk with a retrieved block
tree entry. External services that wish to build their own index, or
analyze blocks can use this to retrieve block data.

The block tree can now be traversed from the tip backwards. This is
guaranteed to work, since the chainstate maintains an internal block
tree index in memory and every block (besides the genesis) has an
ancestor.

The user can use this function to iterate through all blocks in the
chain (starting from the tip). The tip is retrieved from a separate
`Chain` object, which allows distinguishing whether entries are
currently in the best chain. Once the block tree entry for the genesis
block is reached a nullptr is returned if the user attempts to get the
previous entry.
This commit is contained in:
TheCharlatan
2024-06-01 13:03:31 +02:00
parent a263a4caf2
commit 09d0f62638
4 changed files with 179 additions and 1 deletions

View File

@@ -9,6 +9,7 @@
#include <functional>
#include <memory>
#include <optional>
#include <span>
#include <stdexcept>
#include <string>
@@ -598,13 +599,20 @@ public:
}
};
class BlockTreeEntry : View<btck_BlockTreeEntry>
class BlockTreeEntry : public View<btck_BlockTreeEntry>
{
public:
BlockTreeEntry(const btck_BlockTreeEntry* entry)
: View{entry}
{
}
std::optional<BlockTreeEntry> GetPrevious() const
{
auto entry{btck_block_tree_entry_get_previous(get())};
if (!entry) return std::nullopt;
return entry;
}
};
class KernelNotifications
@@ -766,6 +774,22 @@ public:
}
};
class ChainView : public View<btck_Chain>
{
public:
explicit ChainView(const btck_Chain* ptr) : View{ptr} {}
BlockTreeEntry Tip() const
{
return btck_chain_get_tip(get());
}
int32_t Height() const
{
return btck_chain_get_height(get());
}
};
class ChainMan : UniqueHandle<btck_ChainstateManager, btck_chainstate_manager_destroy>
{
public:
@@ -795,6 +819,18 @@ public:
if (new_block) *new_block = _new_block == 1;
return res == 0;
}
ChainView GetChain() const
{
return ChainView{btck_chainstate_manager_get_active_chain(get())};
}
std::optional<Block> ReadBlock(const BlockTreeEntry& entry) const
{
auto block{btck_block_read(get(), entry.get())};
if (!block) return std::nullopt;
return block;
}
};
} // namespace btck