diff --git a/src/bench/mempool_eviction.cpp b/src/bench/mempool_eviction.cpp index f55605caf7..aa50ba582c 100644 --- a/src/bench/mempool_eviction.cpp +++ b/src/bench/mempool_eviction.cpp @@ -1,122 +1,122 @@ // Copyright (c) 2011-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include #include #include #include #include static void AddTx(const CTransactionRef &tx, const Amount &nFee, CTxMemPool &pool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, pool.cs) { int64_t nTime = 0; unsigned int nHeight = 1; bool spendsCoinbase = false; - unsigned int sigOpCost = 4; + unsigned int nSigOpCount = 1; LockPoints lp; pool.addUnchecked(tx->GetId(), CTxMemPoolEntry(tx, nFee, nTime, nHeight, spendsCoinbase, - sigOpCost, lp)); + nSigOpCount, lp)); } // Right now this is only testing eviction performance in an extremely small // mempool. Code needs to be written to generate a much wider variety of // unique transactions for a more meaningful performance measurement. static void MempoolEviction(benchmark::State &state) { CMutableTransaction tx1 = CMutableTransaction(); tx1.vin.resize(1); tx1.vin[0].scriptSig = CScript() << OP_1; tx1.vout.resize(1); tx1.vout[0].scriptPubKey = CScript() << OP_1 << OP_EQUAL; tx1.vout[0].nValue = 10 * COIN; CMutableTransaction tx2 = CMutableTransaction(); tx2.vin.resize(1); tx2.vin[0].scriptSig = CScript() << OP_2; tx2.vout.resize(1); tx2.vout[0].scriptPubKey = CScript() << OP_2 << OP_EQUAL; tx2.vout[0].nValue = 10 * COIN; CMutableTransaction tx3 = CMutableTransaction(); tx3.vin.resize(1); tx3.vin[0].prevout = COutPoint(tx2.GetId(), 0); tx3.vin[0].scriptSig = CScript() << OP_2; tx3.vout.resize(1); tx3.vout[0].scriptPubKey = CScript() << OP_3 << OP_EQUAL; tx3.vout[0].nValue = 10 * COIN; CMutableTransaction tx4 = CMutableTransaction(); tx4.vin.resize(2); tx4.vin[0].prevout = COutPoint(); tx4.vin[0].scriptSig = CScript() << OP_4; tx4.vin[1].prevout = COutPoint(); tx4.vin[1].scriptSig = CScript() << OP_4; tx4.vout.resize(2); tx4.vout[0].scriptPubKey = CScript() << OP_4 << OP_EQUAL; tx4.vout[0].nValue = 10 * COIN; tx4.vout[1].scriptPubKey = CScript() << OP_4 << OP_EQUAL; tx4.vout[1].nValue = 10 * COIN; CMutableTransaction tx5 = CMutableTransaction(); tx5.vin.resize(2); tx5.vin[0].prevout = COutPoint(tx4.GetId(), 0); tx5.vin[0].scriptSig = CScript() << OP_4; tx5.vin[1].prevout = COutPoint(); tx5.vin[1].scriptSig = CScript() << OP_5; tx5.vout.resize(2); tx5.vout[0].scriptPubKey = CScript() << OP_5 << OP_EQUAL; tx5.vout[0].nValue = 10 * COIN; tx5.vout[1].scriptPubKey = CScript() << OP_5 << OP_EQUAL; tx5.vout[1].nValue = 10 * COIN; CMutableTransaction tx6 = CMutableTransaction(); tx6.vin.resize(2); tx6.vin[0].prevout = COutPoint(tx4.GetId(), 1); tx6.vin[0].scriptSig = CScript() << OP_4; tx6.vin[1].prevout = COutPoint(); tx6.vin[1].scriptSig = CScript() << OP_6; tx6.vout.resize(2); tx6.vout[0].scriptPubKey = CScript() << OP_6 << OP_EQUAL; tx6.vout[0].nValue = 10 * COIN; tx6.vout[1].scriptPubKey = CScript() << OP_6 << OP_EQUAL; tx6.vout[1].nValue = 10 * COIN; CMutableTransaction tx7 = CMutableTransaction(); tx7.vin.resize(2); tx7.vin[0].prevout = COutPoint(tx5.GetId(), 0); tx7.vin[0].scriptSig = CScript() << OP_5; tx7.vin[1].prevout = COutPoint(tx6.GetId(), 0); tx7.vin[1].scriptSig = CScript() << OP_6; tx7.vout.resize(2); tx7.vout[0].scriptPubKey = CScript() << OP_7 << OP_EQUAL; tx7.vout[0].nValue = 10 * COIN; tx7.vout[1].scriptPubKey = CScript() << OP_7 << OP_EQUAL; tx7.vout[1].nValue = 10 * COIN; CTxMemPool pool; LOCK2(cs_main, pool.cs); // Create transaction references outside the "hot loop" const CTransactionRef tx1_r{MakeTransactionRef(tx1)}; const CTransactionRef tx2_r{MakeTransactionRef(tx2)}; const CTransactionRef tx3_r{MakeTransactionRef(tx3)}; const CTransactionRef tx4_r{MakeTransactionRef(tx4)}; const CTransactionRef tx5_r{MakeTransactionRef(tx5)}; const CTransactionRef tx6_r{MakeTransactionRef(tx6)}; const CTransactionRef tx7_r{MakeTransactionRef(tx7)}; while (state.KeepRunning()) { AddTx(tx1_r, 10000 * SATOSHI, pool); AddTx(tx2_r, 5000 * SATOSHI, pool); AddTx(tx3_r, 20000 * SATOSHI, pool); AddTx(tx4_r, 7000 * SATOSHI, pool); AddTx(tx5_r, 1000 * SATOSHI, pool); AddTx(tx6_r, 1100 * SATOSHI, pool); AddTx(tx7_r, 9000 * SATOSHI, pool); pool.TrimToSize(pool.DynamicMemoryUsage() * 3 / 4); pool.TrimToSize(GetSerializeSize(*tx1_r, PROTOCOL_VERSION)); } } BENCHMARK(MempoolEviction, 41000); diff --git a/src/bench/rpc_mempool.cpp b/src/bench/rpc_mempool.cpp index 6c7bbe5aac..d7ecd02669 100644 --- a/src/bench/rpc_mempool.cpp +++ b/src/bench/rpc_mempool.cpp @@ -1,44 +1,44 @@ // Copyright (c) 2011-2019 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include #include #include #include #include #include #include static void AddTx(const CTransactionRef &tx, const Amount &fee, CTxMemPool &pool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, pool.cs) { LockPoints lp; pool.addUnchecked(tx->GetId(), CTxMemPoolEntry(tx, fee, /* time */ 0, /* height */ 1, /* spendsCoinbase */ false, - /* sigOpCost */ 4, lp)); + /* sigOpCount */ 1, lp)); } static void RpcMempool(benchmark::State &state) { CTxMemPool pool; LOCK2(cs_main, pool.cs); for (int i = 0; i < 1000; ++i) { CMutableTransaction tx = CMutableTransaction(); tx.vin.resize(1); tx.vin[0].scriptSig = CScript() << OP_1; tx.vout.resize(1); tx.vout[0].scriptPubKey = CScript() << OP_1 << OP_EQUAL; tx.vout[0].nValue = i * CENT; const CTransactionRef tx_r{MakeTransactionRef(tx)}; AddTx(tx_r, /* fee */ i * CENT, pool); } while (state.KeepRunning()) { (void)MempoolToJSON(pool, /*verbose*/ true); } } BENCHMARK(RpcMempool, 40); diff --git a/src/consensus/tx_verify.h b/src/consensus/tx_verify.h index c6a83f5739..cee67487e3 100644 --- a/src/consensus/tx_verify.h +++ b/src/consensus/tx_verify.h @@ -1,104 +1,104 @@ // Copyright (c) 2018 The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_CONSENSUS_TX_VERIFY_H #define BITCOIN_CONSENSUS_TX_VERIFY_H #include #include struct Amount; class CBlockIndex; class CCoinsViewCache; class CTransaction; class CValidationState; /** * Context-independent validity checks for coinbase and non-coinbase * transactions. */ bool CheckRegularTransaction(const CTransaction &tx, CValidationState &state); bool CheckCoinbase(const CTransaction &tx, CValidationState &state); namespace Consensus { struct Params; /** * Check whether all inputs of this transaction are valid (no double spends and * amounts). This does not modify the UTXO set. This does not check scripts and * sigs. * @param[out] txfee Set to the transaction fee if successful. * Preconditions: tx.IsCoinBase() is false. */ bool CheckTxInputs(const CTransaction &tx, CValidationState &state, const CCoinsViewCache &inputs, int nSpendHeight, Amount &txfee); } // namespace Consensus /** * Context dependent validity checks for non coinbase transactions. This * doesn't check the validity of the transaction against the UTXO set, but * simply characteristic that are suceptible to change over time such as feature * activation/deactivation and CLTV. */ bool ContextualCheckTransaction(const Consensus::Params ¶ms, const CTransaction &tx, CValidationState &state, int nHeight, int64_t nLockTimeCutoff, int64_t nMedianTimePast); /** * Calculates the block height and previous block's median time past at which * the transaction will be considered final in the context of BIP 68. * Also removes from the vector of input heights any entries which did not * correspond to sequence locked inputs as they do not affect the calculation. */ std::pair CalculateSequenceLocks(const CTransaction &tx, int flags, std::vector *prevHeights, const CBlockIndex &block); bool EvaluateSequenceLocks(const CBlockIndex &block, std::pair lockPair); /** * Check if transaction is final per BIP 68 sequence numbers and can be included * in a block. Consensus critical. Takes as input a list of heights at which * tx's inputs (in order) confirmed. */ bool SequenceLocks(const CTransaction &tx, int flags, std::vector *prevHeights, const CBlockIndex &block); /** * Count ECDSA signature operations the old-fashioned (pre-0.6) way * @return number of sigops this transaction's outputs will produce when spent * @see CTransaction::FetchInputs */ uint64_t GetSigOpCountWithoutP2SH(const CTransaction &tx, uint32_t flags); /** * Count ECDSA signature operations in pay-to-script-hash inputs. * * @param[in] mapInputs Map of previous transactions that have outputs we're * spending * @return maximum number of sigops required to validate this transaction's * inputs * @see CTransaction::FetchInputs */ uint64_t GetP2SHSigOpCount(const CTransaction &tx, const CCoinsViewCache &mapInputs, uint32_t flags); /** * Compute total signature operation of a transaction. - * @param[in] tx Transaction for which we are computing the cost + * @param[in] tx Transaction for which we are computing the count * @param[in] inputs Map of previous transactions that have outputs we're * spending * @param[in] flags Script verification flags - * @return Total signature operation cost of tx + * @return Total signature operation count of tx */ uint64_t GetTransactionSigOpCount(const CTransaction &tx, const CCoinsViewCache &inputs, uint32_t flags); #endif // BITCOIN_CONSENSUS_TX_VERIFY_H diff --git a/src/miner.h b/src/miner.h index 54439ccd47..e176363d99 100644 --- a/src/miner.h +++ b/src/miner.h @@ -1,229 +1,229 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_MINER_H #define BITCOIN_MINER_H #include #include #include #include #include #include class CBlockIndex; class CChainParams; class Config; class CScript; namespace Consensus { struct Params; } static const bool DEFAULT_PRINTPRIORITY = false; struct CBlockTemplateEntry { CTransactionRef tx; Amount fees; int64_t sigOpCount; CBlockTemplateEntry(CTransactionRef _tx, Amount _fees, int64_t _sigOpCount) : tx(_tx), fees(_fees), sigOpCount(_sigOpCount){}; }; struct CBlockTemplate { CBlock block; std::vector 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(); nModFeesWithAncestors = entry->GetModFeesWithAncestors(); nSigOpCountWithAncestors = entry->GetSigOpCountWithAncestors(); } Amount GetModifiedFee() const { return iter->GetModifiedFee(); } uint64_t GetSizeWithAncestors() const { return nSizeWithAncestors; } Amount GetModFeesWithAncestors() const { return nModFeesWithAncestors; } size_t GetTxSize() const { return iter->GetTxSize(); } const CTransaction &GetTx() const { return iter->GetTx(); } CTxMemPool::txiter iter; uint64_t nSizeWithAncestors; 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; } }; // 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::CompareIteratorById()(a, b); } }; typedef boost::multi_index_container< CTxMemPoolModifiedEntry, boost::multi_index::indexed_by< boost::multi_index::ordered_unique, // sorted by modified ancestor fee rate boost::multi_index::ordered_non_unique< // Reuse same tag from CTxMemPool's similar index boost::multi_index::tag, boost::multi_index::identity, CompareTxMemPoolEntryByAncestorFee>>> indexed_modified_transaction_set; typedef indexed_modified_transaction_set::nth_index<0>::type::iterator modtxiter; typedef indexed_modified_transaction_set::index::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.nSigOpCountWithAncestors -= iter->GetSigOpCount(); } CTxMemPool::txiter iter; }; /** Generate a new block, without valid proof-of-work */ class BlockAssembler { private: // The constructed block template std::unique_ptr pblocktemplate; // A convenience pointer that always refers to the CBlock in pblocktemplate CBlock *pblock; // Configuration parameters for the block size uint64_t nMaxGeneratedBlockSize; CFeeRate blockMinFeeRate; // Information on the current status of the block uint64_t nBlockSize; uint64_t nBlockTx; uint64_t nBlockSigOps; Amount nFees; CTxMemPool::setEntries inBlock; // Chain context for the block int nHeight; int64_t nLockTimeCutoff; int64_t nMedianTimePast; const CChainParams &chainparams; const CTxMemPool *mempool; public: struct Options { Options(); uint64_t nExcessiveBlockSize; uint64_t nMaxGeneratedBlockSize; CFeeRate blockMinFeeRate; }; BlockAssembler(const Config &config, const CTxMemPool &_mempool); BlockAssembler(const CChainParams ¶ms, const CTxMemPool &_mempool, const Options &options); /** Construct a new block template with coinbase to scriptPubKeyIn */ std::unique_ptr CreateNewBlock(const CScript &scriptPubKeyIn); uint64_t GetMaxGeneratedBlockSize() const { return nMaxGeneratedBlockSize; } private: // utility functions /** Clear the block's state and prepare for assembling a new block */ void resetBlock(); /** Add a tx to the block */ void AddToBlock(CTxMemPool::txiter iter); // 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). */ void addPackageTxs(int &nPackagesSelected, int &nDescendantsUpdated) EXCLUSIVE_LOCKS_REQUIRED(mempool->cs); // 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; + bool TestPackage(uint64_t packageSize, int64_t packageSigOpCount) 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, 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 &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); }; /** Modify the extranonce in a block */ void IncrementExtraNonce(CBlock *pblock, const CBlockIndex *pindexPrev, uint64_t nExcessiveBlockSize, unsigned int &nExtraNonce); int64_t UpdateTime(CBlockHeader *pblock, const Consensus::Params ¶ms, const CBlockIndex *pindexPrev); #endif // BITCOIN_MINER_H diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index ba8a66d1df..ef6bcc33d8 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -1,198 +1,198 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. // NOTE: This file is intended to be customised by the end user, and includes // only local node policy logic #include #include