#ifndef BITCOIN_INTERFACES_MINING_H
#define BITCOIN_INTERFACES_MINING_H
#include <consensus/amount.h>
#include <interfaces/types.h>
#include <node/types.h>
#include <primitives/block.h>
#include <primitives/transaction.h>
#include <uint256.h>
#include <util/time.h>
#include <cstdint>
#include <memory>
#include <optional>
#include <vector>
namespace node {
struct NodeContext;
}
class BlockValidationState;
class CScript;
namespace interfaces {
class BlockTemplate
{
public:
virtual ~BlockTemplate() = default;
virtual CBlockHeader getBlockHeader() = 0;
virtual CBlock getBlock() = 0;
virtual std::vector<CAmount> getTxFees() = 0;
virtual std::vector<int64_t> getTxSigops() = 0;
virtual CTransactionRef getCoinbaseTx() = 0;
virtual std::vector<unsigned char> getCoinbaseCommitment() = 0;
virtual int getWitnessCommitmentIndex() = 0;
virtual std::vector<uint256> getCoinbaseMerklePath() = 0;
virtual bool submitSolution(uint32_t version, uint32_t timestamp, uint32_t nonce, CTransactionRef coinbase) = 0;
virtual std::unique_ptr<BlockTemplate> waitNext(const node::BlockWaitOptions options = {}) = 0;
};
class Mining
{
public:
virtual ~Mining() = default;
virtual bool isTestChain() = 0;
virtual bool isInitialBlockDownload() = 0;
virtual std::optional<BlockRef> getTip() = 0;
virtual std::optional<BlockRef> waitTipChanged(uint256 current_tip, MillisecondsDouble timeout = MillisecondsDouble::max()) = 0;
virtual std::unique_ptr<BlockTemplate> createNewBlock(const node::BlockCreateOptions& options = {}) = 0;
virtual bool checkBlock(const CBlock& block, const node::BlockCheckOptions& options, std::string& reason, std::string& debug) = 0;
virtual node::NodeContext* context() { return nullptr; }
};
std::unique_ptr<Mining> MakeMining(node::NodeContext& node);
}
#endif