Repository: bitcoin/bitcoin
File: src/kernel/bitcoinkernel.cpp (C++)

Code before:
    delete block;
}

btck_Block* btck_block_read(const btck_ChainstateManager* chainman, const btck_BlockTreeEntry* entry)
{
    auto block{std::make_shared<CBlock>()};
    if (!btck_ChainstateManager::get(chainman).m_chainman->m_blockman.ReadBlock(*block, btck_BlockTreeEntry::get(entry))) {
        LogError("Failed to read block.");
        return nullptr;
    }
    return btck_Block::create(block);
}

int32_t btck_block_tree_entry_get_height(const btck_BlockTreeEntry* entry)
{
    return btck_BlockTreeEntry::get(entry).nHeight;
}

const btck_BlockHash* btck_block_tree_entry_get_block_hash(const btck_BlockTreeEntry* entry)
{
    return btck_BlockHash::ref(btck_BlockTreeEntry::get(entry).phashBlock);
}

btck_BlockHash* btck_block_hash_create(const unsigned char block_hash[32])
{
    return btck_BlockHash::create(std::span<const unsigned char>{block_hash, 32});
}

btck_BlockHash* btck_block_hash_copy(const btck_BlockHash* block_hash)
{
    return btck_BlockHash::copy(block_hash);
}

void btck_block_hash_to_bytes(const btck_BlockHash* block_hash, unsigned char output[32])
{
    std::memcpy(output, btck_BlockHash::get(block_hash).begin(), 32);
}

int btck_block_hash_equals(const btck_BlockHash* hash1, const btck_BlockHash* hash2)
{
    return btck_BlockHash::get(hash1) == btck_BlockHash::get(hash2);
}

void btck_block_hash_destroy(btck_BlockHash* hash)
{
    delete hash;
}

btck_BlockSpentOutputs* btck_block_spent_outputs_read(const btck_ChainstateManager* chainman, const btck_BlockTreeEntry* entry)
{
    auto block_undo{std::make_shared<CBlockUndo>()};

Review comment (refactor):
_response to https://github.com/bitcoin/bitcoin/pull/33855#issuecomment-3526237850_

@alexanderwiederin opening this thread for easier focus. Are you suggesting we 1) implement `btck_block_tree_entry_equals` with a hash equality check, or 2) to not expose `btck_block_tree_entry_equals` at all and let the user define it however they want (such as using hash equality), or 3) something else?

If 1), I don't see the benefit? Pointer comparisons are faster, and are conceptually correct, and what we use internally. Because the implementation is opaque, we can refactor this however we like to, as long as we ensure that `btck_block_tree_entry_equals` returns `true` whenever the `btck_BlockTreeEntry` objects refer to the same block, as committed to in the (new) contract specified in the docstring.

If 2), I don't think ambiguity is good. E.g. we could specify in the `btck_BlockTreeEntry` docstring that two entries are equal when their hash are equal, but relying on an actual interface is more ergonomic and safer, and the function is trivial to implement?

If 3) can you please elaborate on your concerns?

Code after:
    delete block;
}

btck_Block* btck_block_read(const btck_ChainstateManager* chainman, const btck_BlockTreeEntry* entry)
{
    auto block{std::make_shared<CBlock>()};
    if (!btck_ChainstateManager::get(chainman).m_chainman->m_blockman.ReadBlock(*block, btck_BlockTreeEntry::get(entry))) {
        LogError("Failed to read block.");
        return nullptr;
    }
    return btck_Block::create(block);
}

int32_t btck_block_tree_entry_get_height(const btck_BlockTreeEntry* entry)
{
    return btck_BlockTreeEntry::get(entry).nHeight;
}

const btck_BlockHash* btck_block_tree_entry_get_block_hash(const btck_BlockTreeEntry* entry)
{
    return btck_BlockHash::ref(btck_BlockTreeEntry::get(entry).phashBlock);
}

int btck_block_tree_entry_equals(const btck_BlockTreeEntry* entry1, const btck_BlockTreeEntry* entry2)
{
    return &btck_BlockTreeEntry::get(entry1) == &btck_BlockTreeEntry::get(entry2);
}

btck_BlockHash* btck_block_hash_create(const unsigned char block_hash[32])
{
    return btck_BlockHash::create(std::span<const unsigned char>{block_hash, 32});
}

btck_BlockHash* btck_block_hash_copy(const btck_BlockHash* block_hash)
{
    return btck_BlockHash::copy(block_hash);
}

void btck_block_hash_to_bytes(const btck_BlockHash* block_hash, unsigned char output[32])
{
    std::memcpy(output, btck_BlockHash::get(block_hash).begin(), 32);
}

int btck_block_hash_equals(const btck_BlockHash* hash1, const btck_BlockHash* hash2)
{
    return btck_BlockHash::get(hash1) == btck_BlockHash::get(hash2);
}

void btck_block_hash_destroy(btck_BlockHash* hash)
{
    delete hash;