Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add fmt to miner, mempool and validation #2613

Merged
merged 1 commit into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
479 changes: 285 additions & 194 deletions src/miner.cpp

Large diffs are not rendered by default.

214 changes: 104 additions & 110 deletions src/miner.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,19 @@
#ifndef DEFI_MINER_H
#define DEFI_MINER_H

#include <primitives/block.h>
#include <key.h>
#include <dfi/res.h>
#include <key.h>
#include <primitives/block.h>
#include <timedata.h>
#include <txmempool.h>
#include <validation.h>

#include <stdint.h>
#include <memory>
#include <optional>
#include <stdint.h>

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index_container.hpp>

class CBlockIndex;
class CChainParams;
Expand All @@ -27,16 +27,17 @@ class CScript;
class CAnchor;
struct EvmTxPreApplyContext;

namespace Consensus { struct Params; };
namespace Consensus {
struct Params;
};

static const bool DEFAULT_GENERATE = false;

static const bool DEFAULT_PRINTPRIORITY = false;

extern TxOrderings txOrdering;

struct CBlockTemplate
{
struct CBlockTemplate {
CBlock block;
std::vector<CAmount> vTxFees;
std::vector<int64_t> vTxSigOpsCost;
Expand All @@ -46,8 +47,7 @@ struct CBlockTemplate
// Container for tracking updates to ancestor feerate as we include (parent)
// transactions in a block
struct CTxMemPoolModifiedEntry {
explicit CTxMemPoolModifiedEntry(CTxMemPool::txiter entry)
{
explicit CTxMemPoolModifiedEntry(CTxMemPool::txiter entry) {
iter = entry;
nSizeWithAncestors = entry->GetSizeWithAncestors();
nModFeesWithAncestors = entry->GetModFeesWithAncestors();
Expand All @@ -58,7 +58,7 @@ struct CTxMemPoolModifiedEntry {
uint64_t GetSizeWithAncestors() const { return nSizeWithAncestors; }
CAmount GetModFeesWithAncestors() const { return nModFeesWithAncestors; }
size_t GetTxSize() const { return iter->GetTxSize(); }
const CTransaction& GetTx() const { return iter->GetTx(); }
const CTransaction &GetTx() const { return iter->GetTx(); }
int64_t GetTime() const { return iter->GetTime(); }

CTxMemPool::txiter iter;
Expand All @@ -73,68 +73,55 @@ struct CTxMemPoolModifiedEntry {
* as key in other indexes.
*/
struct CompareCTxMemPoolIter {
bool operator()(const CTxMemPool::txiter& a, const CTxMemPool::txiter& b) const
{
return &(*a) < &(*b);
}
bool operator()(const CTxMemPool::txiter &a, const CTxMemPool::txiter &b) const { return &(*a) < &(*b); }
};

struct modifiedentry_iter {
typedef CTxMemPool::txiter result_type;
result_type operator() (const CTxMemPoolModifiedEntry &entry) const
{
return entry.iter;
}
result_type operator()(const CTxMemPoolModifiedEntry &entry) const { return entry.iter; }
};

// A comparator that sorts transactions based on number of ancestors.
// This is sufficient to sort an ancestor package in an order that is valid
// to appear in a block.
struct CompareTxIterByAncestorCount {
bool operator()(const CTxMemPool::txiter &a, const CTxMemPool::txiter &b) const
{
if (a->GetCountWithAncestors() != b->GetCountWithAncestors())
bool operator()(const CTxMemPool::txiter &a, const CTxMemPool::txiter &b) const {
if (a->GetCountWithAncestors() != b->GetCountWithAncestors()) {
return a->GetCountWithAncestors() < b->GetCountWithAncestors();
}
return CompareTxMemPoolEntryByEntryTime()(*a, *b);
}
};

// A comparator that sorts transactions based on tx entry time.
struct CompareTxIterByEntryTime {
bool operator()(const CTxMemPool::txiter &a, const CTxMemPool::txiter &b) const
{
if (a->GetTime() == b->GetTime())
bool operator()(const CTxMemPool::txiter &a, const CTxMemPool::txiter &b) const {
if (a->GetTime() == b->GetTime()) {
return CompareTxIterByAncestorCount()(a, b);
}
return CompareTxMemPoolEntryByEntryTime()(*a, *b);
}
};

typedef boost::multi_index_container<
CTxMemPoolModifiedEntry,
boost::multi_index::indexed_by<
boost::multi_index::ordered_unique<
modifiedentry_iter,
CompareCTxMemPoolIter
>,
// sorted by modified ancestor fee rate
boost::multi_index::ordered_non_unique<
// Reuse same tag from CTxMemPool's similar index
boost::multi_index::tag<ancestor_score>,
boost::multi_index::identity<CTxMemPoolModifiedEntry>,
CompareTxMemPoolEntryByAncestorFee
>
>
> indexed_modified_transaction_set;
boost::multi_index::indexed_by<boost::multi_index::ordered_unique<modifiedentry_iter, CompareCTxMemPoolIter>,
// sorted by modified ancestor fee rate
boost::multi_index::ordered_non_unique<
// Reuse same tag from CTxMemPool's similar index
boost::multi_index::tag<ancestor_score>,
boost::multi_index::identity<CTxMemPoolModifiedEntry>,
CompareTxMemPoolEntryByAncestorFee>>>
indexed_modified_transaction_set;

typedef indexed_modified_transaction_set::nth_index<0>::type::iterator modtxiter;
typedef indexed_modified_transaction_set::index<ancestor_score>::type::iterator modtxscoreiter;

struct update_for_parent_inclusion
{
explicit update_for_parent_inclusion(CTxMemPool::txiter it) : iter(it) {}
struct update_for_parent_inclusion {
explicit update_for_parent_inclusion(CTxMemPool::txiter it)
: iter(it) {}

void operator() (CTxMemPoolModifiedEntry &e)
{
void operator()(CTxMemPoolModifiedEntry &e) {
e.nModFeesWithAncestors -= iter->GetFee();
e.nSizeWithAncestors -= iter->GetTxSize();
e.nSigOpCostWithAncestors -= iter->GetSigOpCost();
Expand All @@ -144,13 +131,12 @@ struct update_for_parent_inclusion
};

/** Generate a new block, without valid proof-of-work */
class BlockAssembler
{
class BlockAssembler {
private:
// The constructed block template
std::unique_ptr<CBlockTemplate> pblocktemplate;
// A convenience pointer that always refers to the CBlock in pblocktemplate
CBlock* pblock;
CBlock *pblock;

// Configuration parameters for the block size
bool fIncludeWitness;
Expand All @@ -167,7 +153,7 @@ class BlockAssembler
// Chain context for the block
int nHeight;
int64_t nLockTimeCutoff;
const CChainParams& chainparams;
const CChainParams &chainparams;

public:
struct Options {
Expand All @@ -176,11 +162,13 @@ class BlockAssembler
CFeeRate blockMinFeeRate;
};

explicit BlockAssembler(const CChainParams& params);
BlockAssembler(const CChainParams& params, const Options& options);
explicit BlockAssembler(const CChainParams &params);
BlockAssembler(const CChainParams &params, const Options &options);

/** Construct a new block template with coinbase to scriptPubKeyIn */
ResVal<std::unique_ptr<CBlockTemplate>> CreateNewBlock(const CScript& scriptPubKeyIn, int64_t blockTime = 0, const EvmAddressData& beneficiary = {});
ResVal<std::unique_ptr<CBlockTemplate>> CreateNewBlock(const CScript &scriptPubKeyIn,
int64_t blockTime = 0,
const EvmAddressData &beneficiary = {});

inline static std::optional<int64_t> m_last_block_num_txs{};
inline static std::optional<int64_t> m_last_block_weight{};
Expand All @@ -198,88 +186,94 @@ class BlockAssembler

// Methods for how to add transactions to a block.
/** Add transactions based on feerate including unconfirmed ancestors
* Increments nPackagesSelected / nDescendantsUpdated with corresponding
* statistics from the package selection (for logging statistics). */
template<class T>
void addPackageTxs(int &nPackagesSelected, int &nDescendantsUpdated, int nHeight, std::map<uint256, CAmount> &txFees, BlockContext& blockCtx) EXCLUSIVE_LOCKS_REQUIRED(mempool.cs);
* Increments nPackagesSelected / nDescendantsUpdated with corresponding
* statistics from the package selection (for logging statistics). */
template <class T>
void addPackageTxs(int &nPackagesSelected,
int &nDescendantsUpdated,
int nHeight,
std::map<uint256, CAmount> &txFees,
BlockContext &blockCtx) EXCLUSIVE_LOCKS_REQUIRED(mempool.cs);

// helper functions for addPackageTxs()
/** Remove confirmed (inBlock) entries from given set */
void onlyUnconfirmed(CTxMemPool::setEntries& testSet);
void onlyUnconfirmed(CTxMemPool::setEntries &testSet);
/** Test if a new package would "fit" in the block */
bool TestPackage(uint64_t packageSize, int64_t packageSigOpsCost) const;
/** Perform checks on each transaction in a package:
* locktime, premature-witness, serialized size (if necessary)
* These checks should always succeed, and they're here
* only as an extra check in case of suboptimal node configuration */
bool TestPackageTransactions(const CTxMemPool::setEntries& package);
* locktime, premature-witness, serialized size (if necessary)
* These checks should always succeed, and they're here
* only as an extra check in case of suboptimal node configuration */
bool TestPackageTransactions(const CTxMemPool::setEntries &package);
/** Return true if given transaction from mapTx has already been evaluated,
* or if the transaction's cached data in mapTx is incorrect. */
bool SkipMapTxEntry(CTxMemPool::txiter it, indexed_modified_transaction_set &mapModifiedTx, CTxMemPool::setEntries &failedTx) EXCLUSIVE_LOCKS_REQUIRED(mempool.cs);
* or if the transaction's cached data in mapTx is incorrect. */
bool SkipMapTxEntry(CTxMemPool::txiter it,
indexed_modified_transaction_set &mapModifiedTx,
CTxMemPool::setEntries &failedTx) EXCLUSIVE_LOCKS_REQUIRED(mempool.cs);
/** Sort the package in an order that is valid to appear in a block */
void SortForBlock(const CTxMemPool::setEntries& package, std::vector<CTxMemPool::txiter>& sortedEntries);
void SortForBlock(const CTxMemPool::setEntries &package, std::vector<CTxMemPool::txiter> &sortedEntries);
/** Add descendants of given transactions to mapModifiedTx with ancestor
* state updated assuming given transactions are inBlock. Returns number
* of updated descendants. */
int UpdatePackagesForAdded(const CTxMemPool::setEntries& alreadyAdded, indexed_modified_transaction_set &mapModifiedTx) EXCLUSIVE_LOCKS_REQUIRED(mempool.cs);
* state updated assuming given transactions are inBlock. Returns number
* of updated descendants. */
int UpdatePackagesForAdded(const CTxMemPool::setEntries &alreadyAdded,
indexed_modified_transaction_set &mapModifiedTx) EXCLUSIVE_LOCKS_REQUIRED(mempool.cs);
/** Run EVM transaction checks */
bool EvmTxPreapply(EvmTxPreApplyContext& ctx);
bool EvmTxPreapply(EvmTxPreApplyContext &ctx);
};

/** Modify the extranonce in a block */
void IncrementExtraNonce(CBlock* pblock, const CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev);
void IncrementExtraNonce(CBlock *pblock, const CBlockIndex *pindexPrev, unsigned int &nExtraNonce);
int64_t UpdateTime(CBlockHeader *pblock, const Consensus::Params &consensusParams, const CBlockIndex *pindexPrev);

namespace pos {
// The main staking routine.
// Creates stakes using CWallet API, creates PoS kernels and mints blocks.
// Uses Args.getWallets() to receive and update wallets list.

extern AtomicMutex cs_MNLastBlockCreationAttemptTs;
extern AtomicMutex cs_MNLastBlockCreationAttemptTs;

class ThreadStaker {
public:
class ThreadStaker {
public:
struct Args {
int32_t nMint = -1;
int64_t nMaxTries = -1;
CScript coinbaseScript = CScript();
CKey minterKey = CKey();
CKeyID operatorID = {};
};

struct Args {
int32_t nMint = -1;
int64_t nMaxTries = -1;
CScript coinbaseScript = CScript();
CKey minterKey = CKey();
CKeyID operatorID = {};
};
/// always forward by value to avoid dangling pointers
void operator()(std::vector<Args> stakerParams, CChainParams chainparams);
};

/// always forward by value to avoid dangling pointers
void operator()(std::vector<Args> stakerParams, CChainParams chainparams);
};
class Staker {
private:
static uint256 lastBlockSeen;

class Staker {
private:
static uint256 lastBlockSeen;

public:
enum class Status {
error,
initWaiting,
stakeWaiting,
stakeReady,
minted,
};

Staker::Status init(const CChainParams& chainparams);
Staker::Status stake(const CChainParams& chainparams, const ThreadStaker::Args& args);

// declaration static variables
// Map to store [master node id : last block creation attempt timestamp] for local master nodes
static std::map<uint256, int64_t> mapMNLastBlockCreationAttemptTs;

// Variables to manage search time across threads
static int64_t nLastCoinStakeSearchTime;
static int64_t nFutureTime;

private:
template <typename F>
void withSearchInterval(F&& f, int64_t height);
public:
enum class Status {
error,
initWaiting,
stakeWaiting,
stakeReady,
minted,
};
}

#endif // DEFI_MINER_H
Staker::Status init(const CChainParams &chainparams);
Staker::Status stake(const CChainParams &chainparams, const ThreadStaker::Args &args);

// declaration static variables
// Map to store [master node id : last block creation attempt timestamp] for local master nodes
static std::map<uint256, int64_t> mapMNLastBlockCreationAttemptTs;

// Variables to manage search time across threads
static int64_t nLastCoinStakeSearchTime;
static int64_t nFutureTime;

private:
template <typename F>
void withSearchInterval(F &&f, int64_t height);
};
} // namespace pos

#endif // DEFI_MINER_H
Loading