diff --git a/src/bench/wallet_balance.cpp b/src/bench/wallet_balance.cpp index 1956133c1..a50fca88d 100644 --- a/src/bench/wallet_balance.cpp +++ b/src/bench/wallet_balance.cpp @@ -1,95 +1,98 @@ // Copyright (c) 2012-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 #include #include -#include -#include + +#include static void WalletBalance(benchmark::Bench &bench, const bool set_dirty, const bool add_watchonly, const bool add_mine) { TestingSetup test_setup{ CBaseChainParams::REGTEST, /* extra_args */ { "-nodebuglogfile", "-nodebug", }, }; const auto &ADDRESS_WATCHONLY = ADDRESS_BCHREG_UNSPENDABLE; const Config &config = GetConfig(); NodeContext node; std::unique_ptr chain = interfaces::MakeChain(node, config.GetChainParams()); CWallet wallet{chain.get(), WalletLocation(), WalletDatabase::CreateMock()}; { wallet.SetupLegacyScriptPubKeyMan(); bool first_run; if (wallet.LoadWallet(first_run) != DBErrors::LOAD_OK) { assert(false); } } auto handler = chain->handleNotifications({&wallet, [](CWallet *) {}}); const std::optional address_mine{ add_mine ? std::optional{getnewaddress(config, wallet)} : std::nullopt}; if (add_watchonly) { importaddress(wallet, ADDRESS_WATCHONLY); } for (int i = 0; i < 100; ++i) { generatetoaddress(config, test_setup.m_node, address_mine.value_or(ADDRESS_WATCHONLY)); generatetoaddress(config, test_setup.m_node, ADDRESS_WATCHONLY); } SyncWithValidationInterfaceQueue(); // Cache auto bal = wallet.GetBalance(); bench.run([&] { if (set_dirty) { wallet.MarkDirty(); } bal = wallet.GetBalance(); if (add_mine) { assert(bal.m_mine_trusted > Amount::zero()); } if (add_watchonly) { assert(bal.m_watchonly_trusted > Amount::zero()); } }); } static void WalletBalanceDirty(benchmark::Bench &bench) { WalletBalance(bench, /* set_dirty */ true, /* add_watchonly */ true, /* add_mine */ true); } static void WalletBalanceClean(benchmark::Bench &bench) { WalletBalance(bench, /* set_dirty */ false, /* add_watchonly */ true, /* add_mine */ true); } static void WalletBalanceMine(benchmark::Bench &bench) { WalletBalance(bench, /* set_dirty */ false, /* add_watchonly */ false, /* add_mine */ true); } static void WalletBalanceWatch(benchmark::Bench &bench) { WalletBalance(bench, /* set_dirty */ false, /* add_watchonly */ true, /* add_mine */ false); } BENCHMARK(WalletBalanceDirty); BENCHMARK(WalletBalanceClean); BENCHMARK(WalletBalanceMine); BENCHMARK(WalletBalanceWatch); diff --git a/src/miner.h b/src/miner.h index bd4f90701..570c1e661 100644 --- a/src/miner.h +++ b/src/miner.h @@ -1,235 +1,236 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-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. #ifndef BITCOIN_MINER_H #define BITCOIN_MINER_H #include #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; } uint64_t GetVirtualSizeWithAncestors() const; Amount GetModFeesWithAncestors() const { return nModFeesWithAncestors; } size_t GetTxSize() const { return iter->GetTxSize(); } size_t GetTxVirtualSize() const { return iter->GetTxVirtualSize(); } 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; uint64_t nMaxGeneratedBlockSigChecks; 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 &m_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; } static std::optional m_last_block_num_txs; static std::optional m_last_block_size; 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(m_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 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(m_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(m_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 CChainParams &chainParams, const CBlockIndex *pindexPrev); #endif // BITCOIN_MINER_H diff --git a/src/node/psbt.h b/src/node/psbt.h index d13edeaff..cb47a7058 100644 --- a/src/node/psbt.h +++ b/src/node/psbt.h @@ -1,65 +1,67 @@ // Copyright (c) 2009-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. #ifndef BITCOIN_NODE_PSBT_H #define BITCOIN_NODE_PSBT_H #include +#include + /** * Holds an analysis of one input from a PSBT */ struct PSBTInputAnalysis { //! Whether we have UTXO information for this input bool has_utxo; //! Whether the input has all required information including signatures bool is_final; //! Which of the BIP 174 roles needs to handle this input next PSBTRole next; //! Pubkeys whose BIP32 derivation path is missing std::vector missing_pubkeys; //! Pubkeys whose signatures are missing std::vector missing_sigs; //! Hash160 of redeem script, if missing uint160 missing_redeem_script; }; /** * Holds the results of AnalyzePSBT (miscellaneous information about a PSBT) */ struct PSBTAnalysis { //! Estimated weight of the transaction std::optional estimated_vsize; //! Estimated feerate (fee / weight) of the transaction std::optional estimated_feerate; //! Amount of fee being paid by the transaction std::optional fee; //! More information about the individual inputs of the transaction std::vector inputs; //! Which of the BIP 174 roles needs to handle the transaction next PSBTRole next; //! Error message std::string error; void SetInvalid(std::string err_msg) { estimated_vsize = std::nullopt; estimated_feerate = std::nullopt; fee = std::nullopt; inputs.clear(); next = PSBTRole::CREATOR; error = err_msg; } }; /** * Provides helpful miscellaneous information about where a PSBT is in the * signing workflow. * * @param[in] psbtx the PSBT to analyze * @return A PSBTAnalysis with information about the provided PSBT. */ PSBTAnalysis AnalyzePSBT(PartiallySignedTransaction psbtx); #endif // BITCOIN_NODE_PSBT_H diff --git a/src/psbt.h b/src/psbt.h index 205b46a2b..12bc90a73 100644 --- a/src/psbt.h +++ b/src/psbt.h @@ -1,581 +1,583 @@ // Copyright (c) 2009-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. #ifndef BITCOIN_PSBT_H #define BITCOIN_PSBT_H #include #include #include #include #include