Changeset View
Changeset View
Standalone View
Standalone View
src/miner.h
Show First 20 Lines • Show All 106 Lines • ▼ Show 20 Lines | |||||
}; | }; | ||||
struct CBlockTemplate { | struct CBlockTemplate { | ||||
CBlock block; | CBlock block; | ||||
std::vector<CBlockTemplateEntry> entries; | std::vector<CBlockTemplateEntry> entries; | ||||
}; | }; | ||||
// Container for tracking updates to ancestor feerate as we include (parent) | |||||
// transactions in a block | |||||
struct CTxMemPoolModifiedEntry { | |||||
explicit CTxMemPoolModifiedEntry(CTxMemPool::txiter entry) { | |||||
iter = entry; | |||||
nSizeWithAncestors = entry->GetSizeWithAncestors(); | |||||
nBillableSizeWithAncestors = entry->GetBillableSizeWithAncestors(); | |||||
nModFeesWithAncestors = entry->GetModFeesWithAncestors(); | |||||
nSigOpCountWithAncestors = entry->GetSigOpCountWithAncestors(); | |||||
} | |||||
CTxMemPool::txiter iter; | |||||
uint64_t nSizeWithAncestors; | |||||
uint64_t nBillableSizeWithAncestors; | |||||
Amount nModFeesWithAncestors; | |||||
int64_t nSigOpCountWithAncestors; | |||||
}; | |||||
/** | |||||
* Comparator for CTxMemPool::txiter objects. | |||||
* It simply compares the internal memory address of the CTxMemPoolEntry object | |||||
* pointed to. This means it has no meaning, and is only useful for using them | |||||
* as key in other indexes. | |||||
*/ | |||||
struct CompareCTxMemPoolIter { | |||||
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; | |||||
} | |||||
}; | |||||
// This matches the calculation in CompareTxMemPoolEntryByAncestorFee, | |||||
// except operating on CTxMemPoolModifiedEntry. | |||||
// TODO: refactor to avoid duplication of this logic. | |||||
struct CompareModifiedEntry { | |||||
bool operator()(const CTxMemPoolModifiedEntry &a, | |||||
const CTxMemPoolModifiedEntry &b) const { | |||||
double f1 = b.nSizeWithAncestors * (a.nModFeesWithAncestors / SATOSHI); | |||||
double f2 = a.nSizeWithAncestors * (b.nModFeesWithAncestors / SATOSHI); | |||||
if (f1 == f2) { | |||||
return CTxMemPool::CompareIteratorByHash()(a.iter, b.iter); | |||||
} | |||||
return f1 > f2; | |||||
} | |||||
}; | |||||
// 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()) { | |||||
return a->GetCountWithAncestors() < b->GetCountWithAncestors(); | |||||
} | |||||
return CTxMemPool::CompareIteratorByHash()(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>, | |||||
CompareModifiedEntry>>> | |||||
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) {} | |||||
void operator()(CTxMemPoolModifiedEntry &e) { | |||||
e.nModFeesWithAncestors -= iter->GetFee(); | |||||
e.nSizeWithAncestors -= iter->GetTxSize(); | |||||
e.nBillableSizeWithAncestors -= iter->GetTxBillableSize(); | |||||
e.nSigOpCountWithAncestors -= iter->GetSigOpCount(); | |||||
} | |||||
CTxMemPool::txiter iter; | |||||
}; | |||||
/** Generate a new block, without valid proof-of-work */ | /** Generate a new block, without valid proof-of-work */ | ||||
class BlockAssembler { | class BlockAssembler { | ||||
private: | private: | ||||
typedef std::unordered_set<TxId, SaltedTxidHasher> TxIdSet; | typedef std::unordered_set<TxId, SaltedTxidHasher> TxIdSet; | ||||
// The constructed block template | // The constructed block template | ||||
std::unique_ptr<CBlockTemplate> pblocktemplate; | std::unique_ptr<CBlockTemplate> pblocktemplate; | ||||
// A convenience pointer that always refers to the CBlock in pblocktemplate | // A convenience pointer that always refers to the CBlock in pblocktemplate | ||||
Show All 38 Lines | private: | ||||
// Methods for how to add transactions to a block. | // Methods for how to add transactions to a block. | ||||
/** Add transactions based on tx "priority" */ | /** Add transactions based on tx "priority" */ | ||||
void addPriorityTxs(); | void addPriorityTxs(); | ||||
/** Add transactions based on feerate including unconfirmed ancestors | /** Add transactions based on feerate including unconfirmed ancestors | ||||
* Increments nPackagesSelected / nDescendantsUpdated with corresponding | * Increments nPackagesSelected / nDescendantsUpdated with corresponding | ||||
* statistics from the package selection (for logging statistics). */ | * statistics from the package selection (for logging statistics). */ | ||||
void addPackageTxs(int &nPackagesSelected, int &nDescendantsUpdated); | void addPackageTxs(int &nPackagesSelected, int &nDescendantsUpdated); | ||||
// Old version of addPackageTxs | |||||
// TODO: DELET THIS ONII-CHAN | |||||
void accuratelyAddPackageTxs(int &nPackagesSelected, | |||||
int &nDescendantsUpdated); | |||||
/** Enum for the results from TestForBlock */ | /** Enum for the results from TestForBlock */ | ||||
enum class TestForBlockResult : uint8_t { | enum class TestForBlockResult : uint8_t { | ||||
TXFits = 0, | TXFits = 0, | ||||
TXCantFit = 1, | TXCantFit = 1, | ||||
BlockFinished = 3, | BlockFinished = 3, | ||||
}; | }; | ||||
// helper function for addPriorityTxs | // helper function for addPriorityTxs | ||||
/** Test if tx will still "fit" in the block */ | /** Test if tx will still "fit" in the block */ | ||||
TestForBlockResult TestForBlock(CTxMemPool::txiter iter); | TestForBlockResult TestForBlock(CTxMemPool::txiter iter); | ||||
/** Test if tx still has unconfirmed parents not yet in block */ | /** Test if tx still has unconfirmed parents not yet in block */ | ||||
bool isStillDependent(CTxMemPool::txiter iter); | bool isStillDependent(CTxMemPool::txiter iter); | ||||
// helper functions for addPackageTxs() | |||||
/** Remove confirmed (inBlock) entries from given set */ | |||||
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, 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, | |||||
const TxIdSet &failedTx); | |||||
/** Sort the package in an order that is valid to appear in a block */ | |||||
void SortForBlock(const CTxMemPool::setEntries &package, | |||||
CTxMemPool::txiter entry, | |||||
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); | |||||
int UpdatePackagesForAdded(const TxIdSet &alreadyAdded, | |||||
indexed_modified_transaction_set &mapModifiedTx); | |||||
}; | }; | ||||
/** Modify the extranonce in a block */ | /** Modify the extranonce in a block */ | ||||
void IncrementExtraNonce(const Config &config, CBlock *pblock, | void IncrementExtraNonce(const Config &config, CBlock *pblock, | ||||
const CBlockIndex *pindexPrev, | const CBlockIndex *pindexPrev, | ||||
unsigned int &nExtraNonce); | unsigned int &nExtraNonce); | ||||
int64_t UpdateTime(CBlockHeader *pblock, const Config &config, | int64_t UpdateTime(CBlockHeader *pblock, const Config &config, | ||||
const CBlockIndex *pindexPrev); | const CBlockIndex *pindexPrev); | ||||
#endif // BITCOIN_MINER_H | #endif // BITCOIN_MINER_H |