Changeset View
Changeset View
Standalone View
Standalone View
src/avalanche/processor.h
Show First 20 Lines • Show All 90 Lines • ▼ Show 20 Lines | |||||
public: | public: | ||||
VoteItemUpdate(AnyVoteItem itemIn, VoteStatus statusIn) | VoteItemUpdate(AnyVoteItem itemIn, VoteStatus statusIn) | ||||
: item(std::move(itemIn)), status(statusIn) {} | : item(std::move(itemIn)), status(statusIn) {} | ||||
const VoteStatus &getStatus() const { return status; } | const VoteStatus &getStatus() const { return status; } | ||||
const AnyVoteItem &getVoteItem() const { return item; } | const AnyVoteItem &getVoteItem() const { return item; } | ||||
}; | }; | ||||
struct VoteMapComparator { | class VoteMapComparator { | ||||
const CTxMemPool *mempool{nullptr}; | |||||
public: | |||||
VoteMapComparator() {} | |||||
VoteMapComparator(const CTxMemPool *mempoolIn) : mempool(mempoolIn) {} | |||||
bool operator()(const AnyVoteItem &lhs, const AnyVoteItem &rhs) const { | bool operator()(const AnyVoteItem &lhs, const AnyVoteItem &rhs) const { | ||||
// If the variants are of different types, sort them by variant index | // If the variants are of different types, sort them by variant index | ||||
if (lhs.index() != rhs.index()) { | if (lhs.index() != rhs.index()) { | ||||
return lhs.index() < rhs.index(); | return lhs.index() < rhs.index(); | ||||
} | } | ||||
return std::visit( | return std::visit( | ||||
variant::overloaded{ | variant::overloaded{ | ||||
[](const ProofRef &lhs, const ProofRef &rhs) { | [](const ProofRef &lhs, const ProofRef &rhs) { | ||||
return ProofComparatorByScore()(lhs, rhs); | return ProofComparatorByScore()(lhs, rhs); | ||||
}, | }, | ||||
[](const CBlockIndex *lhs, const CBlockIndex *rhs) { | [](const CBlockIndex *lhs, const CBlockIndex *rhs) { | ||||
// Reverse ordering so we get the highest work first | // Reverse ordering so we get the highest work first | ||||
return CBlockIndexWorkComparator()(rhs, lhs); | return CBlockIndexWorkComparator()(rhs, lhs); | ||||
}, | }, | ||||
[](const CTransactionRef &lhs, const CTransactionRef &rhs) { | [this](const CTransactionRef &lhs, const CTransactionRef &rhs) { | ||||
return lhs->GetId() < rhs->GetId(); | const TxId &lhsTxId = lhs->GetId(); | ||||
const TxId &rhsTxId = rhs->GetId(); | |||||
// If there is no mempool, sort by TxId. Note that polling | |||||
// for txs is currently not supported if there is no mempool | |||||
// so this is only a safety net. | |||||
if (!mempool) { | |||||
return lhsTxId < rhsTxId; | |||||
} | |||||
LOCK(mempool->cs); | |||||
auto lhsOptIter = mempool->GetIter(lhsTxId); | |||||
auto rhsOptIter = mempool->GetIter(rhsTxId); | |||||
// If the transactions are not in the mempool, tie by TxId | |||||
if (!lhsOptIter && !rhsOptIter) { | |||||
return lhsTxId < rhsTxId; | |||||
} | |||||
// If only one is in the mempool, pick that one | |||||
if (lhsOptIter.has_value() != rhsOptIter.has_value()) { | |||||
return !!lhsOptIter; | |||||
} | |||||
// Both are in the mempool, select the highest fee rate | |||||
// including the fee deltas | |||||
return CompareTxMemPoolEntryByModifiedFeeRate{}( | |||||
**lhsOptIter, **rhsOptIter); | |||||
}, | }, | ||||
[](const auto &lhs, const auto &rhs) { | [](const auto &lhs, const auto &rhs) { | ||||
// This serves 2 purposes: | // This serves 2 purposes: | ||||
// - This makes sure that we don't forget to implement a | // - This makes sure that we don't forget to implement a | ||||
// comparison case when adding a new variant type. | // comparison case when adding a new variant type. | ||||
// - This avoids having to write all the cross type cases | // - This avoids having to write all the cross type cases | ||||
// which are already handled by the index sort above. | // which are already handled by the index sort above. | ||||
// Because the compiler has no way to determine that, we | // Because the compiler has no way to determine that, we | ||||
▲ Show 20 Lines • Show All 250 Lines • Show Last 20 Lines |