Repository: bitcoin/bitcoin
File: src/node/interfaces.cpp (C++)

Code before:
class MinerImpl : public Mining
{
public:
    explicit MinerImpl(NodeContext& node) : m_node(node) {}

    bool isTestChain() override
    {
        return chainman().GetParams().IsTestChain();
    }

    bool isInitialBlockDownload() override
    {
        return chainman().IsInitialBlockDownload();
    }

    std::optional<uint256> getTipHash() override
    {
        LOCK(::cs_main);
        CBlockIndex* tip{chainman().ActiveChain().Tip()};
        if (!tip) return {};
        return tip->GetBlockHash();
    }

    bool processNewBlock(const std::shared_ptr<const CBlock>& block, bool* new_block) override
    {
        return chainman().ProcessNewBlock(block, /*force_processing=*/true, /*min_pow_checked=*/true, /*new_block=*/new_block);
    }

    unsigned int getTransactionsUpdated() override
    {
        return context()->mempool->GetTransactionsUpdated();
    }

    bool testBlockValidity(const CBlock& block, bool check_merkle_root, BlockValidationState& state) override
    {
        LOCK(cs_main);
        CBlockIndex* tip{chainman().ActiveChain().Tip()};
        // Fail if the tip updated before the lock was taken
        if (block.hashPrevBlock != tip->GetBlockHash()) {
            state.Error("Block does not connect to current chain tip.");
            return false;
        }

        return TestBlockValidity(state, chainman().GetParams(), chainman().ActiveChainstate(), block, tip, /*fCheckPOW=*/false, check_merkle_root);
    }

    std::unique_ptr<CBlockTemplate> createNewBlock(const CScript& script_pub_key, const BlockCreateOptions& options) override
    {
        BlockAssembler::Options assemble_options{options};
        ApplyArgsManOptions(*Assert(m_node.args), assemble_options);
        return BlockAssembler{chainman().ActiveChainstate(), context()->mempool.get(), assemble_options}.CreateNewBlock(script_pub_key);

Review comment (suggestion):
In commit "Add getCoinbaseMerklePath() to Mining interface" (1f5f16d166f8944d532aadc382b30f68a06720e2)

Instead of implementing this function in `node/interfaces.cpp` file it would be better to add a standalone `GetCoinBaseMerklePath(const CBlock&block)` function or a new `CBlock` method that the interface method could call. This would keep the `interfaces.cpp` file simple, and let it just contain glue code instead of more complicated functionality. It would also make the merkle path functionality easier to test, and more accessible to code not using the interface classes.

Code after:

class BlockTemplateImpl : public BlockTemplate
{
public:
    explicit BlockTemplateImpl(std::unique_ptr<CBlockTemplate> block_template) : m_block_template(std::move(block_template))
    {
        assert(m_block_template);
    }

    CBlockHeader getBlockHeader() override
    {
        return m_block_template->block;
    }

    CBlock getBlock() override
    {
        return m_block_template->block;
    }

    std::vector<CAmount> getTxFees() override
    {
        return m_block_template->vTxFees;
    }

    std::vector<int64_t> getTxSigops() override
    {
        return m_block_template->vTxSigOpsCost;
    }

    CTransactionRef getCoinbaseTx() override
    {
        return m_block_template->block.vtx[0];
    }

    std::vector<unsigned char> getCoinbaseCommitment() override
    {
        return m_block_template->vchCoinbaseCommitment;
    }

    int getWitnessCommitmentIndex() override
    {
        return GetWitnessCommitmentIndex(m_block_template->block);
    }

    const std::unique_ptr<CBlockTemplate> m_block_template;
};

class MinerImpl : public Mining
{
public:
    explicit MinerImpl(NodeContext& node) : m_node(node) {}