비트 코 인 소스 코드 분석 (6) - 데이터 구조 - 거래 탱크
23546 단어 비트 코 인 소스 코드 분석
우 리 는 거래 가 방송 되 고 광부 에 게 받 아들 여지 면 광부 들 이 거래 를 현지의 거래 탱크 에 넣 을 것 이라는 것 을 알 고 있다. 모든 광부 들 은 자신의 거래 탱크 에 해당 하 는 제한 을 설정 하여 거래 수량 이 너무 많 지 않 고 광부 들 이 포장 거래 를 블록 에 할 때 일정한 우선 순위 에 따라 거래 를 선택한다.최대한 많은 거래 비 를 받 을 수 있 도록 하 겠 습 니 다.거래 풀 에 대해 주로 두 가지 구조
CTxMemPoolEntry
와 CTxMemPool
를 소개 한다. 첫 번 째 는 거래 풀 에 있 는 모든 요소 의 기본 구조 이 고 두 번 째 는 전체 거래 풀 에 포 함 된 모든 정보 이다.0x01 CTxMemPoolEntry
/**
* CTxMemPoolEntry ,
* entry mempool ,
*
*/
class CTxMemPoolEntry
{
private:
CTransactionRef tx; //
CAmount nFee; // //!< Cached to avoid expensive parent-transaction lookups
size_t nTxWeight; //!< ... and avoid recomputing tx weight (also used for GetTxSize())
size_t nUsageSize; // //!< ... and total memory usage
int64_t nTime; // //!< Local time when entering the mempool
unsigned int entryHeight; // //!< Chain height when entering the mempool
bool spendsCoinbase; // CoinBase
int64_t sigOpCost; //!< Total sigop cost
int64_t feeDelta; //
LockPoints lockPoints; //
// , ,
uint64_t nCountWithDescendants; //
uint64_t nSizeWithDescendants; //
CAmount nModFeesWithDescendants; // ,
//
uint64_t nCountWithAncestors;
uint64_t nSizeWithAncestors;
CAmount nModFeesWithAncestors;
int64_t nSigOpCostWithAncestors;
public:
CTxMemPoolEntry(const CTransactionRef& _tx, const CAmount& _nFee,
int64_t _nTime, unsigned int _entryHeight,
bool spendsCoinbase,
int64_t nSigOpsCost, LockPoints lp);
const CTransaction& GetTx() const { return *this->tx; }
CTransactionRef GetSharedTx() const { return this->tx; }
const CAmount& GetFee() const { return nFee; }
size_t GetTxSize() const;
size_t GetTxWeight() const { return nTxWeight; }
int64_t GetTime() const { return nTime; }
unsigned int GetHeight() const { return entryHeight; }
int64_t GetSigOpCost() const { return sigOpCost; }
int64_t GetModifiedFee() const { return nFee + feeDelta; }
size_t DynamicMemoryUsage() const { return nUsageSize; }
const LockPoints& GetLockPoints() const { return lockPoints; }
//
void UpdateDescendantState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount);
//
void UpdateAncestorState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount, int modifySigOps);
// feeDelta,
void UpdateFeeDelta(int64_t feeDelta);
// LockPoint
void UpdateLockPoints(const LockPoints& lp);
uint64_t GetCountWithDescendants() const { return nCountWithDescendants; }
uint64_t GetSizeWithDescendants() const { return nSizeWithDescendants; }
CAmount GetModFeesWithDescendants() const { return nModFeesWithDescendants; }
bool GetSpendsCoinbase() const { return spendsCoinbase; }
uint64_t GetCountWithAncestors() const { return nCountWithAncestors; }
uint64_t GetSizeWithAncestors() const { return nSizeWithAncestors; }
CAmount GetModFeesWithAncestors() const { return nModFeesWithAncestors; }
int64_t GetSigOpCostWithAncestors() const { return nSigOpCostWithAncestors; }
mutable size_t vTxHashesIdx; //!< Index in mempool's vTxHashes
};
0x02 CTxMemPool
/**
* , 。
* , 。
* ,
* , “ ” 。
* boost::multi_index mapTx ,
* :
* - hash
* - ( )
* - mempool
* -
* , mempool ,
* , ,
* 。
*/
class CTxMemPool
{
private:
uint32_t nCheckFrequency; // 2^32
unsigned int nTransactionsUpdated; //!< Used by getblocktemplate to trigger CreateNewBlock() invocation
CBlockPolicyEstimator* minerPolicyEstimator;
uint64_t totalTxSize; // mempool ,
uint64_t cachedInnerUsage; //map
mutable int64_t lastRollingFeeUpdate;
mutable bool blockSinceLastRollingFeeBump;
mutable double rollingMinimumFeeRate; // pool
void trackPackageRemoved(const CFeeRate& rate);
public:
static const int ROLLING_FEE_HALFLIFE = 60 * 60 * 12; // public only for testing
typedef boost::multi_index_container<
CTxMemPoolEntry,
boost::multi_index::indexed_by<
// sorted by txid, hash
boost::multi_index::hashed_unique,
// sorted by fee rate,
boost::multi_index::ordered_non_unique<
boost::multi_index::tag,
boost::multi_index::identity,
CompareTxMemPoolEntryByDescendantScore
>,
// sorted by entry time,
boost::multi_index::ordered_non_unique<
boost::multi_index::tag,
boost::multi_index::identity,
CompareTxMemPoolEntryByEntryTime
>,
// sorted by score (for mining prioritization),
boost::multi_index::ordered_unique<
boost::multi_index::tag,
boost::multi_index::identity,
CompareTxMemPoolEntryByScore
>,
// sorted by fee rate with ancestors,
boost::multi_index::ordered_non_unique<
boost::multi_index::tag,
boost::multi_index::identity,
CompareTxMemPoolEntryByAncestorFee
>
>
> indexed_transaction_set;
mutable CCriticalSection cs;
indexed_transaction_set mapTx;
typedef indexed_transaction_set::nth_index<0>::type::iterator txiter;
std::vector<std::pair > vTxHashes; //
struct CompareIteratorByHash {
bool operator()(const txiter &a, const txiter &b) const {
return a->GetTx().GetHash() < b->GetTx().GetHash();
}
};
typedef std::set setEntries;
const setEntries & GetMemPoolParents(txiter entry) const;
const setEntries & GetMemPoolChildren(txiter entry) const;
private:
typedef std::map cacheMap;
struct TxLinks {
setEntries parents;
setEntries children;
};
typedef std::map txlinksMap;
txlinksMap mapLinks;
void UpdateParent(txiter entry, txiter parent, bool add);
void UpdateChild(txiter entry, txiter child, bool add);
std::vector<:const_iterator/> GetSortedDepthAndScore() const;
public:
indirectmapconst CTransaction*> mapNextTx;
std::map mapDeltas;
/** mempool
*/
explicit CTxMemPool(CBlockPolicyEstimator* estimator = nullptr);
/**
* sanity-check, check pool ,
* , mapNextTx 。
* sanity-check, check
*/
void check(const CCoinsViewCache *pcoins) const;
void setSanityCheck(double dFrequency = 1.0) { nCheckFrequency = dFrequency * 4294967295.0; }
/**
* addUnchecked ,
* addUnchecked CalculateMemPoolAncestors(),
* addUnchecked
*/
bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, bool validFeeEstimate = true);
bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, setEntries &setAncestors, bool validFeeEstimate = true);
void removeRecursive(const CTransaction &tx, MemPoolRemovalReason reason = MemPoolRemovalReason::UNKNOWN);
void removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags);
void removeConflicts(const CTransaction &tx);
void removeForBlock(const std::vector & vtx, unsigned int nBlockHeight);
void clear();
void _clear(); //lock free
bool CompareDepthAndScore(const uint256& hasha, const uint256& hashb);
void queryHashes(std::vector & vtxid);
bool isSpent(const COutPoint& outpoint);
unsigned int GetTransactionsUpdated() const;
void AddTransactionsUpdated(unsigned int n);
/**
* mempool
*/
bool HasNoInputsOf(const CTransaction& tx) const;
/** CreateNewBlock */
void PrioritiseTransaction(const uint256& hash, const CAmount& nFeeDelta);
void ApplyDelta(const uint256 hash, CAmount &nFeeDelta) const;
void ClearPrioritisation(const uint256 hash);
public:
/**
* mempool ,
* , ,
* 。
* ,
* updateDescendants true,
* mempool
*/
void RemoveStaged(setEntries &stage, bool updateDescendants, MemPoolRemovalReason reason = MemPoolRemovalReason::UNKNOWN);
/**
* Block mempool
*/
void UpdateTransactionsFromBlock(const std::vector &vHashesToUpdate);
/** mempool entry
* limitAncestorCount =
* limitAncestorSize =
* limitDescendantCount =
* limitDescendantSize =
* errString = limit
* fSearchForParents = mempool ,
* mapLinks , mempool entry true
*/
bool CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, setEntries &setAncestors, uint64_t limitAncestorCount, uint64_t limitAncestorSize, uint64_t limitDescendantCount, uint64_t limitDescendantSize, std::string &errString, bool fSearchForParents = true) const;
/** Populate setDescendants with all in-mempool descendants of hash.
* Assumes that setDescendants includes all in-mempool descendants of anything
* already in it. */
void CalculateDescendants(txiter it, setEntries &setDescendants);
/**
* mempool ,
* incrementalRelayFee feerate 0 。
*/
CFeeRate GetMinFee(size_t sizelimit) const;
/**
* sizelimit ,
* pvNoSpendsRemaining, mempool
* mempool
*/
void TrimToSize(size_t sizelimit, std::vector * pvNoSpendsRemaining=nullptr);
/**
* time ,
*
*/
int Expire(int64_t time);
/** chain limit, false*/
bool TransactionWithinChainLimit(const uint256& txid, size_t chainLimit) const;
unsigned long size()
{
LOCK(cs);
return mapTx.size();
}
uint64_t GetTotalTxSize() const
{
LOCK(cs);
return totalTxSize;
}
bool exists(uint256 hash) const
{
LOCK(cs);
return (mapTx.count(hash) != 0);
}
CTransactionRef get(const uint256& hash) const;
TxMempoolInfo info(const uint256& hash) const;
std::vector infoAll() const;
size_t DynamicMemoryUsage() const;
boost::signals2::signal<void (CTransactionRef)> NotifyEntryAdded;
boost::signals2::signal<void (CTransactionRef, MemPoolRemovalReason)> NotifyEntryRemoved;
private:
/** UpdateForDescendants UpdateTransactionsFromBlock ,
* pool ;
* setExclude (because any descendants in
* setExclude were added to the mempool after the transaction being
* updated and hence their state is already reflected in the parent
* state).
*
* ,cachedDescendants
*/
void UpdateForDescendants(txiter updateIt,
cacheMap &cachedDescendants,
const std::set &setExclude);
/** Update ancestors of hash to add/remove it as a descendant transaction. */
void UpdateAncestorsOf(bool add, txiter hash, setEntries &setAncestors);
/** entry */
void UpdateEntryForAncestors(txiter it, const setEntries &setAncestors);
/** , 。
* updateDescendants true, mempool
*/
void UpdateForRemoveFromMempool(const setEntries &entriesToRemove, bool updateDescendants);
/** Sever link between specified transaction and direct children. */
void UpdateChildrenForRemoval(txiter entry);
/** , removeUnchecked ,
* UpdateForRemoveFromMempool。
* CTxMemPoolEntry setMemPoolParents
* , 。
*/
void removeUnchecked(txiter entry, MemPoolRemovalReason reason = MemPoolRemovalReason::UNKNOWN);
};
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
비트 코 인 소스 코드 분석 (6) - 데이터 구조 - 거래 탱크요약 우 리 는 거래 가 방송 되 고 광부 에 게 받 아들 여지 면 광부 들 이 거래 를 현지의 거래 탱크 에 넣 을 것 이라는 것 을 알 고 있다. 모든 광부 들 은 자신의 거래 탱크 에 해당 하 는 제한 을 설정...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.