LCOV - code coverage report
Current view: top level - src/interfaces - chain.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 252 267 94.4 %
Date: 2020-09-26 01:30:44 Functions: 77 80 96.2 %

          Line data    Source code
       1             : // Copyright (c) 2018-2020 The Bitcoin Core developers
       2             : // Distributed under the MIT software license, see the accompanying
       3             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       4             : 
       5             : #include <interfaces/chain.h>
       6             : 
       7             : #include <chain.h>
       8             : #include <chainparams.h>
       9             : #include <interfaces/handler.h>
      10             : #include <interfaces/wallet.h>
      11             : #include <net.h>
      12             : #include <net_processing.h>
      13             : #include <node/coin.h>
      14             : #include <node/context.h>
      15             : #include <node/transaction.h>
      16             : #include <node/ui_interface.h>
      17             : #include <policy/fees.h>
      18             : #include <policy/policy.h>
      19             : #include <policy/rbf.h>
      20             : #include <policy/settings.h>
      21             : #include <primitives/block.h>
      22             : #include <primitives/transaction.h>
      23             : #include <rpc/protocol.h>
      24             : #include <rpc/server.h>
      25             : #include <shutdown.h>
      26             : #include <sync.h>
      27             : #include <timedata.h>
      28             : #include <txmempool.h>
      29             : #include <uint256.h>
      30             : #include <univalue.h>
      31             : #include <util/system.h>
      32             : #include <validation.h>
      33             : #include <validationinterface.h>
      34             : 
      35             : #include <memory>
      36             : #include <utility>
      37             : 
      38             : namespace interfaces {
      39             : namespace {
      40             : 
      41      182700 : bool FillBlock(const CBlockIndex* index, const FoundBlock& block, UniqueLock<RecursiveMutex>& lock)
      42             : {
      43      182700 :     if (!index) return false;
      44      182048 :     if (block.m_hash) *block.m_hash = index->GetBlockHash();
      45      182048 :     if (block.m_height) *block.m_height = index->nHeight;
      46      182048 :     if (block.m_time) *block.m_time = index->GetBlockTime();
      47      182048 :     if (block.m_max_time) *block.m_max_time = index->GetBlockTimeMax();
      48      182048 :     if (block.m_mtp_time) *block.m_mtp_time = index->GetMedianTimePast();
      49      182048 :     if (block.m_data) {
      50       76915 :         REVERSE_LOCK(lock);
      51       76915 :         if (!ReadBlockFromDisk(*block.m_data, index, Params().GetConsensus())) block.m_data->SetNull();
      52       76915 :     }
      53      182048 :     return true;
      54      182700 : }
      55             : 
      56             : class NotificationsProxy : public CValidationInterface
      57             : {
      58             : public:
      59        1480 :     explicit NotificationsProxy(std::shared_ptr<Chain::Notifications> notifications)
      60        1480 :         : m_notifications(std::move(notifications)) {}
      61        1480 :     virtual ~NotificationsProxy() = default;
      62       18759 :     void TransactionAddedToMempool(const CTransactionRef& tx) override
      63             :     {
      64       18759 :         m_notifications->transactionAddedToMempool(tx);
      65       18759 :     }
      66         447 :     void TransactionRemovedFromMempool(const CTransactionRef& tx, MemPoolRemovalReason reason) override
      67             :     {
      68         447 :         m_notifications->transactionRemovedFromMempool(tx, reason);
      69         447 :     }
      70       45219 :     void BlockConnected(const std::shared_ptr<const CBlock>& block, const CBlockIndex* index) override
      71             :     {
      72       45219 :         m_notifications->blockConnected(*block, index->nHeight);
      73       45219 :     }
      74        2753 :     void BlockDisconnected(const std::shared_ptr<const CBlock>& block, const CBlockIndex* index) override
      75             :     {
      76        2753 :         m_notifications->blockDisconnected(*block, index->nHeight);
      77        2753 :     }
      78       42874 :     void UpdatedBlockTip(const CBlockIndex* index, const CBlockIndex* fork_index, bool is_ibd) override
      79             :     {
      80       42874 :         m_notifications->updatedBlockTip();
      81       42874 :     }
      82         614 :     void ChainStateFlushed(const CBlockLocator& locator) override { m_notifications->chainStateFlushed(locator); }
      83             :     std::shared_ptr<Chain::Notifications> m_notifications;
      84             : };
      85             : 
      86             : class NotificationsHandlerImpl : public Handler
      87             : {
      88             : public:
      89        1480 :     explicit NotificationsHandlerImpl(std::shared_ptr<Chain::Notifications> notifications)
      90         740 :         : m_proxy(std::make_shared<NotificationsProxy>(std::move(notifications)))
      91        1480 :     {
      92         740 :         RegisterSharedValidationInterface(m_proxy);
      93        1480 :     }
      94        2220 :     ~NotificationsHandlerImpl() override { disconnect(); }
      95         740 :     void disconnect() override
      96             :     {
      97         740 :         if (m_proxy) {
      98         740 :             UnregisterSharedValidationInterface(m_proxy);
      99         740 :             m_proxy.reset();
     100         740 :         }
     101         740 :     }
     102             :     std::shared_ptr<NotificationsProxy> m_proxy;
     103             : };
     104             : 
     105             : class RpcHandlerImpl : public Handler
     106             : {
     107             : public:
     108       63720 :     explicit RpcHandlerImpl(const CRPCCommand& command) : m_command(command), m_wrapped_command(&command)
     109       63720 :     {
     110       50392 :         m_command.actor = [this](const JSONRPCRequest& request, UniValue& result, bool last_handler) {
     111       18532 :             if (!m_wrapped_command) return false;
     112             :             try {
     113       18532 :                 return m_wrapped_command->actor(request, result, last_handler);
     114         676 :             } catch (const UniValue& e) {
     115             :                 // If this is not the last handler and a wallet not found
     116             :                 // exception was thrown, return false so the next handler can
     117             :                 // try to handle the request. Otherwise, reraise the exception.
     118         338 :                 if (!last_handler) {
     119           0 :                     const UniValue& code = e["code"];
     120           0 :                     if (code.isNum() && code.get_int() == RPC_WALLET_NOT_FOUND) {
     121           0 :                         return false;
     122             :                     }
     123           0 :                 }
     124         338 :                 throw;
     125         338 :             }
     126       18622 :         };
     127       31860 :         ::tableRPC.appendCommand(m_command.name, &m_command);
     128       63720 :     }
     129             : 
     130       31860 :     void disconnect() final
     131             :     {
     132       31860 :         if (m_wrapped_command) {
     133       31860 :             m_wrapped_command = nullptr;
     134       31860 :             ::tableRPC.removeCommand(m_command.name, &m_command);
     135       31860 :         }
     136       31860 :     }
     137             : 
     138       95580 :     ~RpcHandlerImpl() override { disconnect(); }
     139             : 
     140             :     CRPCCommand m_command;
     141             :     const CRPCCommand* m_wrapped_command;
     142             : };
     143             : 
     144        3351 : class ChainImpl : public Chain
     145             : {
     146             : public:
     147        2236 :     explicit ChainImpl(NodeContext& node) : m_node(node) {}
     148         727 :     Optional<int> getHeight() override
     149             :     {
     150         727 :         LOCK(::cs_main);
     151         727 :         int height = ::ChainActive().Height();
     152         727 :         if (height >= 0) {
     153         694 :             return height;
     154             :         }
     155          33 :         return nullopt;
     156         727 :     }
     157        9573 :     Optional<int> getBlockHeight(const uint256& hash) override
     158             :     {
     159        9573 :         LOCK(::cs_main);
     160        9573 :         CBlockIndex* block = LookupBlockIndex(hash);
     161        9573 :         if (block && ::ChainActive().Contains(block)) {
     162        8926 :             return block->nHeight;
     163             :         }
     164         647 :         return nullopt;
     165        9573 :     }
     166         774 :     uint256 getBlockHash(int height) override
     167             :     {
     168         774 :         LOCK(::cs_main);
     169         774 :         CBlockIndex* block = ::ChainActive()[height];
     170         774 :         assert(block);
     171         774 :         return block->GetBlockHash();
     172         774 :     }
     173           0 :     bool haveBlockOnDisk(int height) override
     174             :     {
     175           0 :         LOCK(cs_main);
     176           0 :         CBlockIndex* block = ::ChainActive()[height];
     177           0 :         return block && ((block->nStatus & BLOCK_HAVE_DATA) != 0) && block->nTx > 0;
     178           0 :     }
     179          80 :     Optional<int> findFirstBlockWithTimeAndHeight(int64_t time, int height, uint256* hash) override
     180             :     {
     181          80 :         LOCK(cs_main);
     182          80 :         CBlockIndex* block = ::ChainActive().FindEarliestAtLeast(time, height);
     183          80 :         if (block) {
     184          80 :             if (hash) *hash = block->GetBlockHash();
     185          80 :             return block->nHeight;
     186             :         }
     187           0 :         return nullopt;
     188          80 :     }
     189         500 :     CBlockLocator getTipLocator() override
     190             :     {
     191         500 :         LOCK(cs_main);
     192         500 :         return ::ChainActive().GetLocator();
     193         500 :     }
     194     1038424 :     bool checkFinalTx(const CTransaction& tx) override
     195             :     {
     196     1038424 :         LOCK(cs_main);
     197     1038424 :         return CheckFinalTx(tx);
     198     1038424 :     }
     199         716 :     Optional<int> findLocatorFork(const CBlockLocator& locator) override
     200             :     {
     201         716 :         LOCK(cs_main);
     202         716 :         if (CBlockIndex* fork = FindForkInGlobalIndex(::ChainActive(), locator)) {
     203         683 :             return fork->nHeight;
     204             :         }
     205          33 :         return nullopt;
     206         716 :     }
     207      105147 :     bool findBlock(const uint256& hash, const FoundBlock& block) override
     208             :     {
     209      105147 :         WAIT_LOCK(cs_main, lock);
     210      105147 :         return FillBlock(LookupBlockIndex(hash), block, lock);
     211      105147 :     }
     212         549 :     bool findFirstBlockWithTimeAndHeight(int64_t min_time, int min_height, const FoundBlock& block) override
     213             :     {
     214         549 :         WAIT_LOCK(cs_main, lock);
     215         549 :         return FillBlock(ChainActive().FindEarliestAtLeast(min_time, min_height), block, lock);
     216         549 :     }
     217       76906 :     bool findNextBlock(const uint256& block_hash, int block_height, const FoundBlock& next, bool* reorg) override {
     218       76906 :         WAIT_LOCK(cs_main, lock);
     219       76906 :         CBlockIndex* block = ChainActive()[block_height];
     220       76906 :         if (block && block->GetBlockHash() != block_hash) block = nullptr;
     221       76906 :         if (reorg) *reorg = !block;
     222       76906 :         return FillBlock(block ? ChainActive()[block_height + 1] : nullptr, next, lock);
     223       76906 :     }
     224          39 :     bool findAncestorByHeight(const uint256& block_hash, int ancestor_height, const FoundBlock& ancestor_out) override
     225             :     {
     226          39 :         WAIT_LOCK(cs_main, lock);
     227          40 :         if (const CBlockIndex* block = LookupBlockIndex(block_hash)) {
     228          39 :             if (const CBlockIndex* ancestor = block->GetAncestor(ancestor_height)) {
     229          77 :                 return FillBlock(ancestor, ancestor_out, lock);
     230             :             }
     231             :         }
     232           1 :         return FillBlock(nullptr, ancestor_out, lock);
     233          39 :     }
     234           5 :     bool findAncestorByHash(const uint256& block_hash, const uint256& ancestor_hash, const FoundBlock& ancestor_out) override
     235             :     {
     236           5 :         WAIT_LOCK(cs_main, lock);
     237           5 :         const CBlockIndex* block = LookupBlockIndex(block_hash);
     238           5 :         const CBlockIndex* ancestor = LookupBlockIndex(ancestor_hash);
     239           5 :         if (block && ancestor && block->GetAncestor(ancestor->nHeight) != ancestor) ancestor = nullptr;
     240           5 :         return FillBlock(ancestor, ancestor_out, lock);
     241           5 :     }
     242          18 :     bool findCommonAncestor(const uint256& block_hash1, const uint256& block_hash2, const FoundBlock& ancestor_out, const FoundBlock& block1_out, const FoundBlock& block2_out) override
     243             :     {
     244          18 :         WAIT_LOCK(cs_main, lock);
     245          18 :         const CBlockIndex* block1 = LookupBlockIndex(block_hash1);
     246          18 :         const CBlockIndex* block2 = LookupBlockIndex(block_hash2);
     247          18 :         const CBlockIndex* ancestor = block1 && block2 ? LastCommonAncestor(block1, block2) : nullptr;
     248             :         // Using & instead of && below to avoid short circuiting and leaving
     249             :         // output uninitialized.
     250          18 :         return FillBlock(ancestor, ancestor_out, lock) & FillBlock(block1, block1_out, lock) & FillBlock(block2, block2_out, lock);
     251          18 :     }
     252        1648 :     void findCoins(std::map<COutPoint, Coin>& coins) override { return FindCoins(m_node, coins); }
     253       77554 :     double guessVerificationProgress(const uint256& block_hash) override
     254             :     {
     255       77554 :         LOCK(cs_main);
     256       77554 :         return GuessVerificationProgress(Params().TxData(), LookupBlockIndex(block_hash));
     257       77554 :     }
     258          30 :     bool hasBlocks(const uint256& block_hash, int min_height, Optional<int> max_height) override
     259             :     {
     260             :         // hasBlocks returns true if all ancestors of block_hash in specified
     261             :         // range have block data (are not pruned), false if any ancestors in
     262             :         // specified range are missing data.
     263             :         //
     264             :         // For simplicity and robustness, min_height and max_height are only
     265             :         // used to limit the range, and passing min_height that's too low or
     266             :         // max_height that's too high will not crash or change the result.
     267          30 :         LOCK(::cs_main);
     268          44 :         if (CBlockIndex* block = LookupBlockIndex(block_hash)) {
     269          30 :             if (max_height && block->nHeight >= *max_height) block = block->GetAncestor(*max_height);
     270        1781 :             for (; block->nStatus & BLOCK_HAVE_DATA; block = block->pprev) {
     271             :                 // Check pprev to not segfault if min_height is too low
     272        1767 :                 if (block->nHeight <= min_height || !block->pprev) return true;
     273             :             }
     274             :         }
     275          14 :         return false;
     276          30 :     }
     277         553 :     RBFTransactionState isRBFOptIn(const CTransaction& tx) override
     278             :     {
     279         553 :         if (!m_node.mempool) return IsRBFOptInEmptyMempool(tx);
     280         553 :         LOCK(m_node.mempool->cs);
     281         553 :         return IsRBFOptIn(tx, *m_node.mempool);
     282         553 :     }
     283         182 :     bool hasDescendantsInMempool(const uint256& txid) override
     284             :     {
     285         182 :         if (!m_node.mempool) return false;
     286         182 :         LOCK(m_node.mempool->cs);
     287         182 :         auto it = m_node.mempool->GetIter(txid);
     288         182 :         return it && (*it)->GetCountWithDescendants() > 1;
     289         182 :     }
     290        1343 :     bool broadcastTransaction(const CTransactionRef& tx,
     291             :         const CAmount& max_tx_fee,
     292             :         bool relay,
     293             :         std::string& err_string) override
     294             :     {
     295        1343 :         const TransactionError err = BroadcastTransaction(m_node, tx, err_string, max_tx_fee, relay, /*wait_callback*/ false);
     296             :         // Chain clients only care about failures to accept the tx to the mempool. Disregard non-mempool related failures.
     297             :         // Note: this will need to be updated if BroadcastTransactions() is updated to return other non-mempool failures
     298             :         // that Chain clients do not need to know about.
     299        1343 :         return TransactionError::OK == err;
     300           0 :     }
     301      426805 :     void getTransactionAncestry(const uint256& txid, size_t& ancestors, size_t& descendants) override
     302             :     {
     303      426805 :         ancestors = descendants = 0;
     304      426805 :         if (!m_node.mempool) return;
     305      426805 :         m_node.mempool->GetTransactionAncestry(txid, ancestors, descendants);
     306      426805 :     }
     307        5388 :     void getPackageLimits(unsigned int& limit_ancestor_count, unsigned int& limit_descendant_count) override
     308             :     {
     309        5388 :         limit_ancestor_count = gArgs.GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT);
     310        5388 :         limit_descendant_count = gArgs.GetArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT);
     311        5388 :     }
     312           6 :     bool checkChainLimits(const CTransactionRef& tx) override
     313             :     {
     314           6 :         if (!m_node.mempool) return true;
     315           6 :         LockPoints lp;
     316           6 :         CTxMemPoolEntry entry(tx, 0, 0, 0, false, 0, lp);
     317           6 :         CTxMemPool::setEntries ancestors;
     318           6 :         auto limit_ancestor_count = gArgs.GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT);
     319           6 :         auto limit_ancestor_size = gArgs.GetArg("-limitancestorsize", DEFAULT_ANCESTOR_SIZE_LIMIT) * 1000;
     320           6 :         auto limit_descendant_count = gArgs.GetArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT);
     321           6 :         auto limit_descendant_size = gArgs.GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT) * 1000;
     322           6 :         std::string unused_error_string;
     323           6 :         LOCK(m_node.mempool->cs);
     324           6 :         return m_node.mempool->CalculateMemPoolAncestors(
     325             :             entry, ancestors, limit_ancestor_count, limit_ancestor_size,
     326             :             limit_descendant_count, limit_descendant_size, unused_error_string);
     327           6 :     }
     328       40407 :     CFeeRate estimateSmartFee(int num_blocks, bool conservative, FeeCalculation* calc) override
     329             :     {
     330       40407 :         return ::feeEstimator.estimateSmartFee(num_blocks, calc, conservative);
     331             :     }
     332       19175 :     unsigned int estimateMaxBlocks() override
     333             :     {
     334       19175 :         return ::feeEstimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE);
     335             :     }
     336       21105 :     CFeeRate mempoolMinFee() override
     337             :     {
     338       21105 :         if (!m_node.mempool) return {};
     339       21105 :         return m_node.mempool->GetMinFee(gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000);
     340       21105 :     }
     341       22907 :     CFeeRate relayMinFee() override { return ::minRelayTxFee; }
     342          93 :     CFeeRate relayIncrementalFee() override { return ::incrementalRelayFee; }
     343       89461 :     CFeeRate relayDustFee() override { return ::dustRelayFee; }
     344         425 :     bool havePruned() override
     345             :     {
     346         425 :         LOCK(cs_main);
     347         425 :         return ::fHavePruned;
     348         425 :     }
     349       13157 :     bool isReadyToBroadcast() override { return !::fImporting && !::fReindex && !isInitialBlockDownload(); }
     350       15784 :     bool isInitialBlockDownload() override { return ::ChainstateActive().IsInitialBlockDownload(); }
     351       77371 :     bool shutdownRequested() override { return ShutdownRequested(); }
     352      136216 :     int64_t getAdjustedTime() override { return GetAdjustedTime(); }
     353        1328 :     void initMessage(const std::string& message) override { ::uiInterface.InitMessage(message); }
     354           0 :     void initWarning(const bilingual_str& message) override { InitWarning(message); }
     355          22 :     void initError(const bilingual_str& message) override { InitError(message); }
     356        3502 :     void showProgress(const std::string& title, int progress, bool resume_possible) override
     357             :     {
     358        3502 :         ::uiInterface.ShowProgress(title, progress, resume_possible);
     359        3502 :     }
     360         740 :     std::unique_ptr<Handler> handleNotifications(std::shared_ptr<Notifications> notifications) override
     361             :     {
     362         740 :         return MakeUnique<NotificationsHandlerImpl>(std::move(notifications));
     363             :     }
     364        4635 :     void waitForNotificationsIfTipChanged(const uint256& old_tip) override
     365             :     {
     366        4635 :         if (!old_tip.IsNull()) {
     367        4635 :             LOCK(::cs_main);
     368        4635 :             if (old_tip == ::ChainActive().Tip()->GetBlockHash()) return;
     369        4635 :         }
     370           8 :         SyncWithValidationInterfaceQueue();
     371        4635 :     }
     372       31860 :     std::unique_ptr<Handler> handleRpc(const CRPCCommand& command) override
     373             :     {
     374       31860 :         return MakeUnique<RpcHandlerImpl>(command);
     375             :     }
     376           2 :     bool rpcEnableDeprecated(const std::string& method) override { return IsDeprecatedRPCEnabled(method); }
     377          39 :     void rpcRunLater(const std::string& name, std::function<void()> fn, int64_t seconds) override
     378             :     {
     379          39 :         RPCRunLater(name, std::move(fn), seconds);
     380          39 :     }
     381         237 :     int rpcSerializationFlags() override { return RPCSerializationFlags(); }
     382          11 :     util::SettingsValue getRwSetting(const std::string& name) override
     383             :     {
     384          11 :         util::SettingsValue result;
     385          22 :         gArgs.LockSettings([&](const util::Settings& settings) {
     386          11 :             if (const util::SettingsValue* value = util::FindKey(settings.rw_settings, name)) {
     387          11 :                 result = *value;
     388          11 :             }
     389          11 :         });
     390             :         return result;
     391          11 :     }
     392           7 :     bool updateRwSetting(const std::string& name, const util::SettingsValue& value) override
     393             :     {
     394          14 :         gArgs.LockSettings([&](util::Settings& settings) {
     395           7 :             if (value.isNull()) {
     396           0 :                 settings.rw_settings.erase(name);
     397           0 :             } else {
     398           7 :                 settings.rw_settings[name] = value;
     399             :             }
     400           7 :         });
     401           7 :         return gArgs.WriteSettingsFile();
     402             :     }
     403         722 :     void requestMempoolTransactions(Notifications& notifications) override
     404             :     {
     405         722 :         if (!m_node.mempool) return;
     406         722 :         LOCK2(::cs_main, m_node.mempool->cs);
     407         840 :         for (const CTxMemPoolEntry& entry : m_node.mempool->mapTx) {
     408         118 :             notifications.transactionAddedToMempool(entry.GetSharedTx());
     409           0 :         }
     410         722 :     }
     411             :     NodeContext& m_node;
     412             : };
     413             : } // namespace
     414             : 
     415        1118 : std::unique_ptr<Chain> MakeChain(NodeContext& node) { return MakeUnique<ChainImpl>(node); }
     416             : 
     417             : } // namespace interfaces

Generated by: LCOV version 1.15