X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fmain.h;h=2cb3ea77fb67bcde3d86d2534997aaec45ce393b;hb=e3af34101250095febe11520d67c6e0070ef3181;hp=6b3001910956b1196e3a62bc29831e98f93a4553;hpb=a2d67b52d688d3044927a3b534d0450b6559f5cd;p=novacoin.git diff --git a/src/main.h b/src/main.h index 6b30019..2cb3ea7 100644 --- a/src/main.h +++ b/src/main.h @@ -5,15 +5,17 @@ #ifndef BITCOIN_MAIN_H #define BITCOIN_MAIN_H +#include + #include "timestamps.h" #include "bignum.h" #include "sync.h" #include "net.h" #include "script.h" #include "scrypt.h" -#include "zerocoin/Zerocoin.h" #include +#include class CWallet; class CBlock; @@ -27,23 +29,29 @@ class CInv; class CRequestTracker; class CNode; +// +// Global state +// + static const unsigned int MAX_BLOCK_SIZE = 1000000; static const unsigned int MAX_BLOCK_SIZE_GEN = MAX_BLOCK_SIZE/2; static const unsigned int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50; static const unsigned int MAX_ORPHAN_TRANSACTIONS = MAX_BLOCK_SIZE/100; static const unsigned int MAX_INV_SZ = 50000; -static const int64 MIN_TX_FEE = CENT/10; -static const int64 MIN_RELAY_TX_FEE = CENT/50; +static const int64_t MIN_TX_FEE = CENT/10; +static const int64_t MIN_RELAY_TX_FEE = CENT/50; -static const int64 MAX_MONEY = 2000000000 * COIN; -static const int64 MAX_MINT_PROOF_OF_WORK = 100 * COIN; -static const int64 MAX_MINT_PROOF_OF_STAKE = 1 * COIN; -static const int64 MIN_TXOUT_AMOUNT = CENT/100; +static const int64_t MAX_MONEY = 2000000000 * COIN; +static const int64_t MAX_MINT_PROOF_OF_WORK = 100 * COIN; +static const int64_t MAX_MINT_PROOF_OF_STAKE = 1 * COIN; +static const int64_t MIN_TXOUT_AMOUNT = CENT/100; -inline bool MoneyRange(int64 nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); } +inline bool MoneyRange(int64_t nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); } // Threshold for nLockTime: below this value it is interpreted as block number, otherwise as UNIX timestamp. static const unsigned int LOCKTIME_THRESHOLD = 500000000; // Tue Nov 5 00:53:20 1985 UTC +// Maximum number of script-checking threads allowed +static const int MAX_SCRIPTCHECK_THREADS = 16; #ifdef USE_UPNP static const int fHaveUPnP = true; @@ -54,17 +62,16 @@ static const int fHaveUPnP = false; static const uint256 hashGenesisBlock("0x00000a060336cbb72fe969666d337b87198b1add2abaa59cca226820b32933a4"); static const uint256 hashGenesisBlockTestNet("0x000c763e402f2436da9ed36c7286f62c3f6e5dbafce9ff289bd43d7459327eb"); -inline int64 PastDrift(int64 nTime) { return nTime - 2 * 60 * 60; } // up to 2 hours from the past -inline int64 FutureDrift(int64 nTime) { return nTime + 2 * 60 * 60; } // up to 2 hours from the future +inline int64_t PastDrift(int64_t nTime) { return nTime - 2 * 60 * 60; } // up to 2 hours from the past +inline int64_t FutureDrift(int64_t nTime) { return nTime + 2 * 60 * 60; } // up to 2 hours from the future -extern libzerocoin::Params* ZCParams; extern CScript COINBASE_FLAGS; extern CCriticalSection cs_main; extern std::map mapBlockIndex; extern std::set > setStakeSeen; extern CBlockIndex* pindexGenesisBlock; -extern unsigned int nStakeMinAge; extern unsigned int nNodeLifespan; +extern unsigned int nStakeMinAge; extern int nCoinbaseMaturity; extern int nBestHeight; extern uint256 nBestChainTrust; @@ -72,36 +79,36 @@ extern uint256 nBestInvalidTrust; extern uint256 hashBestChain; extern CBlockIndex* pindexBest; extern unsigned int nTransactionsUpdated; -extern uint64 nLastBlockTx; -extern uint64 nLastBlockSize; -extern int64 nLastCoinStakeSearchInterval; +extern uint64_t nLastBlockTx; +extern uint64_t nLastBlockSize; +extern int64_t nLastCoinStakeSearchInterval; extern const std::string strMessageMagic; -extern int64 nTimeBestReceived; +extern int64_t nTimeBestReceived; extern CCriticalSection cs_setpwalletRegistered; extern std::set setpwalletRegistered; extern unsigned char pchMessageStart[4]; extern std::map mapOrphanBlocks; // Settings -extern int64 nTransactionFee; -extern int64 nMinimumInputValue; +extern int64_t nTransactionFee; +extern int64_t nMinimumInputValue; extern bool fUseFastIndex; extern unsigned int nDerivationMethodIndex; - -extern bool fEnforceCanonical; +extern int nScriptCheckThreads; // Minimum disk space required - used in CheckDiskSpace() -static const uint64 nMinDiskSpace = 52428800; +static const uint64_t nMinDiskSpace = 52428800; class CReserveKey; class CTxDB; class CTxIndex; +class CScriptCheck; void RegisterWallet(CWallet* pwalletIn); void UnregisterWallet(CWallet* pwalletIn); void SyncWithWallets(const CTransaction& tx, const CBlock* pblock = NULL, bool fUpdate = false, bool fConnect = true); bool ProcessBlock(CNode* pfrom, CBlock* pblock); -bool CheckDiskSpace(uint64 nAdditionalBytes=0); +bool CheckDiskSpace(uint64_t nAdditionalBytes=0); FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb"); FILE* AppendBlockFile(unsigned int& nFileRet); bool LoadBlockIndex(bool fAllowNew=true); @@ -111,12 +118,17 @@ bool ProcessMessages(CNode* pfrom); bool SendMessages(CNode* pto, bool fSendTrickle); bool LoadExternalBlockFile(FILE* fileIn); +// Run an instance of the script checking thread +void ThreadScriptCheck(void* parg); +// Stop the script checking threads +void ThreadScriptCheckQuit(); + bool CheckProofOfWork(uint256 hash, unsigned int nBits); unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfStake); -int64 GetProofOfWorkReward(unsigned int nBits); -int64 GetProofOfStakeReward(int64 nCoinAge, unsigned int nBits, unsigned int nTime, bool bCoinYearOnly=false); -unsigned int ComputeMinWork(unsigned int nBase, int64 nTime); -unsigned int ComputeMinStake(unsigned int nBase, int64 nTime, unsigned int nBlockTime); +int64_t GetProofOfWorkReward(unsigned int nBits, int64_t nFees=0); +int64_t GetProofOfStakeReward(int64_t nCoinAge, unsigned int nBits, unsigned int nTime, bool bCoinYearOnly=false); +unsigned int ComputeMinWork(unsigned int nBase, int64_t nTime); +unsigned int ComputeMinStake(unsigned int nBase, int64_t nTime, unsigned int nBlockTime); int GetNumBlocksOfPeers(); bool IsInitialBlockDownload(); std::string GetWarnings(std::string strFor); @@ -126,8 +138,7 @@ const CBlockIndex* GetLastBlockIndex(const CBlockIndex* pindex, bool fProofOfSta void StakeMiner(CWallet *pwallet); void ResendWalletTransactions(); - - +bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, unsigned int flags, int nHashType); @@ -141,9 +152,9 @@ bool GetWalletFile(CWallet* pwallet, std::string &strWalletFileOut); class CDiskTxPos { public: - unsigned int nFile; - unsigned int nBlockPos; - unsigned int nTxPos; + uint32_t nFile; + uint32_t nBlockPos; + uint32_t nTxPos; CDiskTxPos() { @@ -195,7 +206,7 @@ class CInPoint { public: CTransaction* ptx; - unsigned int n; + uint32_t n; CInPoint() { SetNull(); } CInPoint(CTransaction* ptxIn, unsigned int nIn) { ptx = ptxIn; n = nIn; } @@ -210,7 +221,7 @@ class COutPoint { public: uint256 hash; - unsigned int n; + uint32_t n; COutPoint() { SetNull(); } COutPoint(uint256 hashIn, unsigned int nIn) { hash = hashIn; n = nIn; } @@ -256,7 +267,7 @@ class CTxIn public: COutPoint prevout; CScript scriptSig; - unsigned int nSequence; + uint32_t nSequence; CTxIn() { @@ -336,7 +347,7 @@ public: class CTxOut { public: - int64 nValue; + int64_t nValue; CScript scriptPubKey; CTxOut() @@ -344,7 +355,7 @@ public: SetNull(); } - CTxOut(int64 nValueIn, CScript scriptPubKeyIn) + CTxOut(int64_t nValueIn, CScript scriptPubKeyIn) { nValue = nValueIn; scriptPubKey = scriptPubKeyIn; @@ -433,10 +444,10 @@ class CTransaction public: static const int CURRENT_VERSION=1; int nVersion; - unsigned int nTime; + uint32_t nTime; std::vector vin; std::vector vout; - unsigned int nLockTime; + uint32_t nLockTime; // Denial-of-service detection: mutable int nDoS; @@ -460,7 +471,7 @@ public: void SetNull() { nVersion = CTransaction::CURRENT_VERSION; - nTime = GetAdjustedTime(); + nTime = (uint32_t) GetAdjustedTime(); vin.clear(); vout.clear(); nLockTime = 0; @@ -477,7 +488,7 @@ public: return SerializeHash(*this); } - bool IsFinal(int nBlockHeight=0, int64 nBlockTime=0) const + bool IsFinal(int nBlockHeight=0, int64_t nBlockTime=0) const { // Time based nLockTime implemented in 0.1.6 if (nLockTime == 0) @@ -486,7 +497,7 @@ public: nBlockHeight = nBestHeight; if (nBlockTime == 0) nBlockTime = GetAdjustedTime(); - if ((int64)nLockTime < ((int64)nLockTime < LOCKTIME_THRESHOLD ? (int64)nBlockHeight : nBlockTime)) + if ((int64_t)nLockTime < ((int64_t)nLockTime < LOCKTIME_THRESHOLD ? (int64_t)nBlockHeight : nBlockTime)) return true; BOOST_FOREACH(const CTxIn& txin, vin) if (!txin.IsFinal()) @@ -563,9 +574,9 @@ public: /** Amount of bitcoins spent by this transaction. @return sum of all outputs (note: does not include fees) */ - int64 GetValueOut() const + int64_t GetValueOut() const { - int64 nValueOut = 0; + int64_t nValueOut = 0; BOOST_FOREACH(const CTxOut& txout, vout) { nValueOut += txout.nValue; @@ -583,7 +594,7 @@ public: @return Sum of value of all inputs (scriptSigs) @see CTransaction::FetchInputs */ - int64 GetValueIn(const MapPrevTx& mapInputs) const; + int64_t GetValueIn(const MapPrevTx& mapInputs) const; static bool AllowFree(double dPriority) { @@ -592,7 +603,7 @@ public: return dPriority > COIN * 144 / 250; } - int64 GetMinFee(unsigned int nBlockSize=1, bool fAllowFree=false, enum GetMinFee_mode mode=GMF_BLOCK, unsigned int nBytes = 0) const; + int64_t GetMinFee(unsigned int nBlockSize=1, bool fAllowFree=false, enum GetMinFee_mode mode=GMF_BLOCK, unsigned int nBytes = 0) const; bool ReadFromDisk(CDiskTxPos pos, FILE** pfileRet=NULL) { @@ -608,7 +619,8 @@ public: filein >> *this; } catch (std::exception &e) { - return error("%s() : deserialize or I/O error", __PRETTY_FUNCTION__); + (void)e; + return error("%s() : deserialize or I/O error", BOOST_CURRENT_FUNCTION); } // Return file pointer @@ -646,7 +658,7 @@ public: { std::string str; str += IsCoinBase()? "Coinbase" : (IsCoinStake()? "Coinstake" : "CTransaction"); - str += strprintf("(hash=%s, nTime=%d, ver=%d, vin.size=%"PRIszu", vout.size=%"PRIszu", nLockTime=%d)\n", + str += strprintf("(hash=%s, nTime=%d, ver=%d, vin.size=%" PRIszu ", vout.size=%" PRIszu ", nLockTime=%d)\n", GetHash().ToString().substr(0,10).c_str(), nTime, nVersion, @@ -693,21 +705,50 @@ public: @param[in] pindexBlock @param[in] fBlock true if called from ConnectBlock @param[in] fMiner true if called from CreateNewBlock - @param[in] fStrictPayToScriptHash true if fully validating p2sh transactions + @param[in] fScriptChecks enable scripts validation? + @param[in] flags STRICT_FLAGS script validation flags + @param[in] pvChecks NULL If pvChecks is not NULL, script checks are pushed onto it instead of being performed inline. @return Returns true if all checks succeed */ - bool ConnectInputs(CTxDB& txdb, MapPrevTx inputs, - std::map& mapTestPool, const CDiskTxPos& posThisTx, - const CBlockIndex* pindexBlock, bool fBlock, bool fMiner, bool fStrictPayToScriptHash=true); + bool ConnectInputs(CTxDB& txdb, MapPrevTx inputs, std::map& mapTestPool, const CDiskTxPos& posThisTx, const CBlockIndex* pindexBlock, + bool fBlock, bool fMiner, bool fScriptChecks=true, + unsigned int flags=STRICT_FLAGS, std::vector *pvChecks = NULL); bool ClientConnectInputs(); bool CheckTransaction() const; bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL); - bool GetCoinAge(CTxDB& txdb, uint64& nCoinAge) const; // ppcoin: get transaction coin age + bool GetCoinAge(CTxDB& txdb, uint64_t& nCoinAge) const; // ppcoin: get transaction coin age protected: const CTxOut& GetOutputFor(const CTxIn& input, const MapPrevTx& inputs) const; }; +/** Closure representing one script verification + * Note that this stores references to the spending transaction */ +class CScriptCheck +{ +private: + CScript scriptPubKey; + const CTransaction *ptxTo; + unsigned int nIn; + unsigned int nFlags; + int nHashType; + +public: + CScriptCheck() {} + CScriptCheck(const CTransaction& txFromIn, const CTransaction& txToIn, unsigned int nInIn, unsigned int nFlagsIn, int nHashTypeIn) : + scriptPubKey(txFromIn.vout[txToIn.vin[nInIn].prevout.n].scriptPubKey), + ptxTo(&txToIn), nIn(nInIn), nFlags(nFlagsIn), nHashType(nHashTypeIn) { } + + bool operator()() const; + + void swap(CScriptCheck &check) { + scriptPubKey.swap(check.scriptPubKey); + std::swap(ptxTo, check.ptxTo); + std::swap(nIn, check.nIn); + std::swap(nFlags, check.nFlags); + std::swap(nHashType, check.nHashType); + } +}; @@ -718,7 +759,7 @@ class CMerkleTx : public CTransaction public: uint256 hashBlock; std::vector vMerkleBranch; - int nIndex; + int32_t nIndex; // memory only mutable bool fMerkleVerified; @@ -837,12 +878,12 @@ class CBlock public: // header static const int CURRENT_VERSION=6; - int nVersion; + int32_t nVersion; uint256 hashPrevBlock; uint256 hashMerkleRoot; - unsigned int nTime; - unsigned int nBits; - unsigned int nNonce; + uint32_t nTime; + uint32_t nBits; + uint32_t nNonce; // network and disk std::vector vtx; @@ -909,9 +950,9 @@ public: return scrypt_blockhash(CVOIDBEGIN(nVersion)); } - int64 GetBlockTime() const + int64_t GetBlockTime() const { - return (int64)nTime; + return (int64_t)nTime; } void UpdateTime(const CBlockIndex* pindexPrev); @@ -923,7 +964,7 @@ public: if (nTime >= ENTROPY_SWITCH_TIME || fTestNet) { // Take last bit of block hash as entropy bit - unsigned int nEntropyBit = ((GetHash().Get64()) & 1llu); + unsigned int nEntropyBit = ((GetHash().Get64()) & 1ULL); if (fDebug && GetBoolArg("-printstakemodifier")) printf("GetStakeEntropyBit: nTime=%u hashBlock=%s nEntropyBit=%u\n", nTime, GetHash().ToString().c_str(), nEntropyBit); return nEntropyBit; @@ -934,8 +975,8 @@ public: printf("GetStakeEntropyBit: hashSig=%s", hashSig.ToString().c_str()); hashSig >>= 159; // take the first bit of the hash if (fDebug && GetBoolArg("-printstakemodifier")) - printf(" entropybit=%"PRI64d"\n", hashSig.Get64()); - return hashSig.Get64(); + printf(" entropybit=%" PRId64 "\n", hashSig.Get64()); + return (unsigned int)hashSig.Get64(); } // ppcoin: two types of block: proof-of-work or proof-of-stake @@ -955,11 +996,11 @@ public: } // ppcoin: get max transaction timestamp - int64 GetMaxTransactionTime() const + int64_t GetMaxTransactionTime() const { - int64 maxTransactionTime = 0; + int64_t maxTransactionTime = 0; BOOST_FOREACH(const CTransaction& tx, vtx) - maxTransactionTime = std::max(maxTransactionTime, (int64)tx.nTime); + maxTransactionTime = std::max(maxTransactionTime, (int64_t)tx.nTime); return maxTransactionTime; } @@ -969,7 +1010,7 @@ public: BOOST_FOREACH(const CTransaction& tx, vtx) vMerkleTree.push_back(tx.GetHash()); int j = 0; - for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2) + for (int nSize = (int)vtx.size(); nSize > 1; nSize = (nSize + 1) / 2) { for (int i = 0; i < nSize; i += 2) { @@ -988,7 +1029,7 @@ public: BuildMerkleTree(); std::vector vMerkleBranch; int j = 0; - for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2) + for (int nSize = (int)vtx.size(); nSize > 1; nSize = (nSize + 1) / 2) { int i = std::min(nIndex^1, nSize-1); vMerkleBranch.push_back(vMerkleTree[j+i]); @@ -1056,7 +1097,8 @@ public: filein >> *this; } catch (std::exception &e) { - return error("%s() : deserialize or I/O error", __PRETTY_FUNCTION__); + (void)e; + return error("%s() : deserialize or I/O error", BOOST_CURRENT_FUNCTION); } // Check the header @@ -1070,7 +1112,7 @@ public: void print() const { - printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%"PRIszu", vchBlockSig=%s)\n", + printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%" PRIszu ", vchBlockSig=%s)\n", GetHash().ToString().c_str(), nVersion, hashPrevBlock.ToString().c_str(), @@ -1097,7 +1139,7 @@ public: bool AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos); bool CheckBlock(bool fCheckPOW=true, bool fCheckMerkleRoot=true, bool fCheckSig=true) const; bool AcceptBlock(); - bool GetCoinAge(uint64& nCoinAge) const; // ppcoin: calculate total coin age spent in block + bool GetCoinAge(uint64_t& nCoinAge) const; // ppcoin: calculate total coin age spent in block bool SignBlock(CWallet& keystore); bool CheckBlockSignature(bool fProofOfStake) const; @@ -1123,15 +1165,15 @@ public: const uint256* phashBlock; CBlockIndex* pprev; CBlockIndex* pnext; - unsigned int nFile; - unsigned int nBlockPos; + uint32_t nFile; + uint32_t nBlockPos; uint256 nChainTrust; // ppcoin: trust score of block chain - int nHeight; + int32_t nHeight; - int64 nMint; - int64 nMoneySupply; + int64_t nMint; + int64_t nMoneySupply; - unsigned int nFlags; // ppcoin: block index flags + uint32_t nFlags; // ppcoin: block index flags enum { BLOCK_PROOF_OF_STAKE = (1 << 0), // is proof-of-stake block @@ -1139,20 +1181,20 @@ public: BLOCK_STAKE_MODIFIER = (1 << 2), // regenerated stake modifier }; - uint64 nStakeModifier; // hash modifier for proof-of-stake - unsigned int nStakeModifierChecksum; // checksum of index; in-memeory only + uint64_t nStakeModifier; // hash modifier for proof-of-stake + uint32_t nStakeModifierChecksum; // checksum of index; in-memeory only // proof-of-stake specific fields COutPoint prevoutStake; - unsigned int nStakeTime; + uint32_t nStakeTime; uint256 hashProofOfStake; // block header - int nVersion; - uint256 hashMerkleRoot; - unsigned int nTime; - unsigned int nBits; - unsigned int nNonce; + int32_t nVersion; + uint256 hashMerkleRoot; + uint32_t nTime; + uint32_t nBits; + uint32_t nNonce; CBlockIndex() { @@ -1231,9 +1273,9 @@ public: return *phashBlock; } - int64 GetBlockTime() const + int64_t GetBlockTime() const { - return (int64)nTime; + return (int64_t)nTime; } uint256 GetBlockTrust() const; @@ -1250,11 +1292,11 @@ public: enum { nMedianTimeSpan=11 }; - int64 GetMedianTimePast() const + int64_t GetMedianTimePast() const { - int64 pmedian[nMedianTimeSpan]; - int64* pbegin = &pmedian[nMedianTimeSpan]; - int64* pend = &pmedian[nMedianTimeSpan]; + int64_t pmedian[nMedianTimeSpan]; + int64_t* pbegin = &pmedian[nMedianTimeSpan]; + int64_t* pend = &pmedian[nMedianTimeSpan]; const CBlockIndex* pindex = this; for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev) @@ -1264,7 +1306,7 @@ public: return pbegin[(pend - pbegin)/2]; } - int64 GetMedianTime() const + int64_t GetMedianTime() const { const CBlockIndex* pindex = this; for (int i = 0; i < nMedianTimeSpan/2; i++) @@ -1314,10 +1356,10 @@ public: bool GeneratedStakeModifier() const { - return (nFlags & BLOCK_STAKE_MODIFIER); + return (nFlags & BLOCK_STAKE_MODIFIER) != 0; } - void SetStakeModifier(uint64 nModifier, bool fGeneratedStakeModifier) + void SetStakeModifier(uint64_t nModifier, bool fGeneratedStakeModifier) { nStakeModifier = nModifier; if (fGeneratedStakeModifier) @@ -1326,7 +1368,7 @@ public: std::string ToString() const { - return strprintf("CBlockIndex(nprev=%p, pnext=%p, nFile=%u, nBlockPos=%-6d nHeight=%d, nMint=%s, nMoneySupply=%s, nFlags=(%s)(%d)(%s), nStakeModifier=%016"PRI64x", nStakeModifierChecksum=%08x, hashProofOfStake=%s, prevoutStake=(%s), nStakeTime=%d merkle=%s, hashBlock=%s)", + return strprintf("CBlockIndex(nprev=%p, pnext=%p, nFile=%u, nBlockPos=%-6d nHeight=%d, nMint=%s, nMoneySupply=%s, nFlags=(%s)(%d)(%s), nStakeModifier=%016" PRIx64 ", nStakeModifierChecksum=%08x, hashProofOfStake=%s, prevoutStake=(%s), nStakeTime=%d merkle=%s, hashBlock=%s)", pprev, pnext, nFile, nBlockPos, nHeight, FormatMoney(nMint).c_str(), FormatMoney(nMoneySupply).c_str(), GeneratedStakeModifier() ? "MOD" : "-", GetStakeEntropyBit(), IsProofOfStake()? "PoS" : "PoW", @@ -1594,7 +1636,7 @@ public: void clear(); void queryHashes(std::vector& vtxid); - unsigned long size() + size_t size() { LOCK(cs); return mapTx.size();