BlockQueue.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /*
  2. This file is part of cpp-ethereum.
  3. cpp-ethereum is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or
  6. (at your option) any later version.
  7. cpp-ethereum is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. /** @file BlockQueue.h
  15. * @author Gav Wood <i@gavwood.com>
  16. * @date 2014
  17. */
  18. #pragma once
  19. #include <condition_variable>
  20. #include <thread>
  21. #include <deque>
  22. #include <boost/thread.hpp>
  23. #include <libdevcore/Common.h>
  24. #include <libdevcore/Log.h>
  25. #include <libethcore/Common.h>
  26. #include <libdevcore/Guards.h>
  27. #include <libethcore/Common.h>
  28. #include <libethcore/BlockHeader.h>
  29. #include "VerifiedBlock.h"
  30. namespace dev
  31. {
  32. namespace eth
  33. {
  34. class BlockChain;
  35. struct BlockQueueChannel: public LogChannel { static const char* name(); static const int verbosity = 4; };
  36. struct BlockQueueTraceChannel: public LogChannel { static const char* name(); static const int verbosity = 7; };
  37. #define cblockq dev::LogOutputStream<dev::eth::BlockQueueChannel, true>()
  38. struct BlockQueueStatus
  39. {
  40. size_t importing;
  41. size_t verified;
  42. size_t verifying;
  43. size_t unverified;
  44. size_t future;
  45. size_t unknown;
  46. size_t bad;
  47. };
  48. enum class QueueStatus
  49. {
  50. Ready,
  51. Importing,
  52. UnknownParent,
  53. Bad,
  54. Unknown
  55. };
  56. std::ostream& operator<< (std::ostream& os, QueueStatus const& obj);
  57. /**
  58. * @brief A queue of blocks. Sits between network or other I/O and the BlockChain.
  59. * Sorts them ready for blockchain insertion (with the BlockChain::sync() method).
  60. * @threadsafe
  61. */
  62. class BlockQueue: HasInvariants
  63. {
  64. public:
  65. BlockQueue();
  66. ~BlockQueue();
  67. void setChain(BlockChain const& _bc) { m_bc = &_bc; }
  68. /// Import a block into the queue.
  69. ImportResult import(bytesConstRef _block, bool _isOurs = false);
  70. /// Notes that time has moved on and some blocks that used to be "in the future" may no be valid.
  71. void tick();
  72. /// Grabs at most @a _max of the blocks that are ready, giving them in the correct order for insertion into the chain.
  73. /// Don't forget to call doneDrain() once you're done importing.
  74. void drain(std::vector<VerifiedBlock>& o_out, unsigned _max);
  75. /// Must be called after a drain() call. Notes that the drained blocks have been imported into the blockchain, so we can forget about them.
  76. /// @returns true iff there are additional blocks ready to be processed.
  77. bool doneDrain(h256s const& _knownBad = h256s());
  78. /// Notify the queue that the chain has changed and a new block has attained 'ready' status (i.e. is in the chain).
  79. void noteReady(h256 const& _b) { WriteGuard l(m_lock); noteReady_WITH_LOCK(_b); }
  80. /// Force a retry of all the blocks with unknown parents.
  81. void retryAllUnknown();
  82. /// Get information on the items queued.
  83. std::pair<unsigned, unsigned> items() const { ReadGuard l(m_lock); return std::make_pair(m_readySet.size(), m_unknownSet.size()); }
  84. /// Clear everything.
  85. void clear();
  86. /// Stop all activity, leaves the class in limbo, waiting for destruction
  87. void stop();
  88. /// Return first block with an unknown parent.
  89. h256 firstUnknown() const { ReadGuard l(m_lock); return m_unknownSet.size() ? *m_unknownSet.begin() : h256(); }
  90. /// Get some infomration on the current status.
  91. BlockQueueStatus status() const { ReadGuard l(m_lock); Guard l2(m_verification); return BlockQueueStatus{m_drainingSet.size(), m_verified.size(), m_verifying.size(), m_unverified.size(), m_future.size(), m_unknown.size(), m_knownBad.size()}; }
  92. /// Get some infomration on the given block's status regarding us.
  93. QueueStatus blockStatus(h256 const& _h) const;
  94. template <class T> Handler<> onReady(T const& _t) { return m_onReady.add(_t); }
  95. template <class T> Handler<> onRoomAvailable(T const& _t) { return m_onRoomAvailable.add(_t); }
  96. template <class T> void setOnBad(T const& _t) { m_onBad = _t; }
  97. bool knownFull() const;
  98. bool unknownFull() const;
  99. u256 difficulty() const; // Total difficulty of queueud blocks
  100. bool isActive() const;
  101. private:
  102. struct UnverifiedBlock
  103. {
  104. h256 hash;
  105. h256 parentHash;
  106. bytes block;
  107. };
  108. void noteReady_WITH_LOCK(h256 const& _b);
  109. bool invariants() const override;
  110. void verifierBody();
  111. void collectUnknownBad_WITH_BOTH_LOCKS(h256 const& _bad);
  112. void updateBad_WITH_LOCK(h256 const& _bad);
  113. void drainVerified_WITH_BOTH_LOCKS();
  114. BlockChain const* m_bc; ///< The blockchain into which our imports go.
  115. mutable boost::shared_mutex m_lock; ///< General lock for the sets, m_future and m_unknown.
  116. h256Hash m_drainingSet; ///< All blocks being imported.
  117. h256Hash m_readySet; ///< All blocks ready for chain import.
  118. h256Hash m_unknownSet; ///< Set of all blocks whose parents are not ready/in-chain.
  119. std::unordered_multimap<h256, std::pair<h256, bytes>> m_unknown; ///< For blocks that have an unknown parent; we map their parent hash to the block stuff, and insert once the block appears.
  120. h256Hash m_knownBad; ///< Set of blocks that we know will never be valid.
  121. std::multimap<unsigned, std::pair<h256, bytes>> m_future; ///< Set of blocks that are not yet valid. Ordered by timestamp
  122. Signal<> m_onReady; ///< Called when a subsequent call to import blocks will return a non-empty container. Be nice and exit fast.
  123. Signal<> m_onRoomAvailable; ///< Called when space for new blocks becomes availabe after a drain. Be nice and exit fast.
  124. mutable Mutex m_verification; ///< Mutex that allows writing to m_verified, m_verifying and m_unverified.
  125. std::condition_variable m_moreToVerify; ///< Signaled when m_unverified has a new entry.
  126. std::deque<VerifiedBlock> m_verified; ///< List of blocks, in correct order, verified and ready for chain-import.
  127. std::deque<VerifiedBlock> m_verifying; ///< List of blocks being verified; as long as the block component (bytes) is empty, it's not finished.
  128. std::deque<UnverifiedBlock> m_unverified; ///< List of <block hash, parent hash, block data> in correct order, ready for verification.
  129. std::vector<std::thread> m_verifiers; ///< Threads who only verify.
  130. bool m_deleting = false; ///< Exit condition for verifiers.
  131. std::function<void(Exception&)> m_onBad; ///< Called if we have a block that doesn't verify.
  132. std::atomic<size_t> m_unknownSize; ///< Tracks total size in bytes of all unknown blocks
  133. std::atomic<size_t> m_knownSize; ///< Tracks total size in bytes of all known blocks;
  134. std::atomic<size_t> m_unknownCount; ///< Tracks total count of unknown blocks. Used to avoid additional syncing
  135. std::atomic<size_t> m_knownCount; ///< Tracks total count of known blocks. Used to avoid additional syncing
  136. u256 m_difficulty; ///< Total difficulty of blocks in the queue
  137. u256 m_drainingDifficulty; ///< Total difficulty of blocks in draining
  138. };
  139. std::ostream& operator<<(std::ostream& _out, BlockQueueStatus const& _s);
  140. }
  141. }