24 #include <condition_variable> 27 #include <boost/thread.hpp> 46 #define cblockq dev::LogOutputStream<dev::eth::BlockQueueChannel, true>() 76 std::size_t
size()
const {
return m_size; }
92 m_queue.emplace_back(std::move(_t));
93 m_size +=
m_queue.back().blockData.size();
101 m_size -= t.blockData.size();
113 std::vector<T> removed = removeIf(sha3UnclesEquals(_hash));
114 return !removed.empty();
120 auto const removedBegin = std::remove_if(
m_queue.begin(),
m_queue.end(), _pred);
122 return removeRange(removedBegin,
m_queue.end());
127 auto const it = std::find_if(
m_queue.begin(),
m_queue.end(), sha3UnclesEquals(_hash));
132 m_size -= it->blockData.size();
133 m_size += _t.blockData.size();
142 return [&_hash](
T const& _t) {
return _t.verified.info.sha3Uncles() == _hash; };
145 std::vector<T>
removeRange(
typename std::deque<T>::iterator _begin,
typename std::deque<T>::iterator _end)
147 std::vector<T> ret(std::make_move_iterator(_begin), std::make_move_iterator(_end));
149 for (
auto it = ret.begin(); it != ret.end(); ++it)
150 m_size -= it->blockData.size();
157 std::atomic<size_t> m_size = {0};
160 template<
class KeyType>
164 std::size_t
count()
const {
return m_map.size(); }
166 std::size_t
size()
const {
return m_size; }
168 bool isEmpty()
const {
return m_map.empty(); }
170 KeyType
firstKey()
const {
return m_map.begin()->first; }
180 auto hashAndBlock = std::make_pair(_hash, std::move(_blockData));
181 auto keyAndValue = std::make_pair(_key, std::move(hashAndBlock));
182 m_map.insert(std::move(keyAndValue));
183 m_size += _blockData.size();
188 auto const equalRange = m_map.equal_range(_key);
189 return removeRange(equalRange.first, equalRange.second);
194 return removeRange(m_map.begin(), m_map.upper_bound(_key));
200 std::vector<std::pair<h256, bytes>>
removeRange(
typename BlockMultimap::iterator _begin,
typename BlockMultimap::iterator _end)
202 std::vector<std::pair<h256, bytes>> removed;
203 std::size_t removedSize = 0;
204 for (
auto it = _begin; it != _end; ++it)
206 removed.push_back(std::move(it->second));
207 removedSize += removed.back().second.size();
210 m_size -= removedSize;
211 m_map.erase(_begin, _end);
217 std::atomic<size_t> m_size = {0};
241 void drain(std::vector<VerifiedBlock>& o_out,
unsigned _max);
245 bool doneDrain(
h256s const& _knownBad =
h256s());
251 void retryAllUnknown();
254 std::pair<unsigned, unsigned>
items()
const {
ReadGuard l(m_lock);
return std::make_pair(m_readySet.size(), m_unknownSet.size()); }
274 template <
class T>
void setOnBad(
T const& _t) { m_onBad = _t; }
276 bool knownFull()
const;
277 bool unknownFull()
const;
278 u256 difficulty()
const;
279 bool isActive()
const;
289 void noteReady_WITH_LOCK(
h256 const& _b);
291 bool invariants()
const override;
294 void collectUnknownBad_WITH_BOTH_LOCKS(
h256 const& _bad);
295 void updateBad_WITH_LOCK(
h256 const& _bad);
296 void drainVerified_WITH_BOTH_LOCKS();
298 std::size_t knownSize()
const;
299 std::size_t knownCount()
const;
300 std::size_t unknownSize()
const;
301 std::size_t unknownCount()
const;
322 std::atomic<bool> m_deleting = {
false};
std::size_t count() const
Inheritable for classes that have invariants.
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
Super-duper signal mechanism. TODO: replace with somthing a bit heavier weight.
h256Hash m_drainingSet
All blocks being imported.
std::multimap< dev::FixedHash, std::pair< h256, bytes >> BlockMultimap
void swap(dev::eth::Watch &_a, dev::eth::Watch &_b)
Implements the blockchain database.
void setOnBad(T const &_t)
u256 m_drainingDifficulty
Total difficulty of blocks in draining.
std::vector< T > removeRange(typename std::deque< T >::iterator _begin, typename std::deque< T >::iterator _end)
std::ostream & operator<<(std::ostream &_out, BlockHeader const &_bi)
void noteReady(h256 const &_b)
Notify the queue that the chain has changed and a new block has attained 'ready' status (i...
static const int verbosity
Handler onRoomAvailable(T const &_t)
SizedBlockQueue< UnverifiedBlock > m_unverified
List of <block hash, parent hash, block data> in correct order, ready for verification.
std::pair< unsigned, unsigned > items() const
Get information on the items queued.
SizedBlockQueue< VerifiedBlock > m_verifying
List of blocks being verified; as long as the block component (bytes) is empty, it's not finished...
std::vector< std::thread > m_verifiers
Threads who only verify.
h256Hash m_readySet
All blocks ready for chain import.
concurrent_queue< JitTask > m_queue
Mutex m_verification
Mutex that allows writing to m_verified, m_verifying and m_unverified.
SizedBlockMap< time_t > m_future
Set of blocks that are not yet valid. Ordered by timestamp.
Signal m_onRoomAvailable
Called when space for new blocks becomes availabe after a drain. Be nice and exit fast...
std::vector< std::pair< h256, bytes > > removeRange(typename BlockMultimap::iterator _begin, typename BlockMultimap::iterator _end)
void insert(KeyType const &_key, h256 const &_hash, bytes &&_blockData)
std::shared_ptr< typename Signal< Args... >::HandlerAux > Handler
std::vector< byte > bytes
h256 firstUnknown() const
Return first block with an unknown parent.
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void >> u256
std::vector< std::pair< h256, bytes > > removeByKeyEqual(KeyType const &_key)
boost::shared_lock< boost::shared_mutex > ReadGuard
h256Hash m_unknownSet
Set of all blocks whose parents are not ready/in-chain.
Signal m_onReady
Called when a subsequent call to import blocks will return a non-empty container. Be nice and exit fa...
std::vector< std::pair< h256, bytes > > removeByKeyNotGreater(KeyType const &_key)
boost::unique_lock< boost::shared_mutex > WriteGuard
static std::function< bool(T const &)> sha3UnclesEquals(h256 const &_hash)
std::vector< T > dequeueMultiple(std::size_t _n)
Handler onReady(T const &_t)
std::condition_variable m_moreToVerify
Signaled when m_unverified has a new entry.
u256 m_difficulty
Total difficulty of blocks in the queue.
boost::shared_mutex m_lock
General lock for the sets, m_future and m_unknown.
void setChain(BlockChain const &_bc)
bool replace(h256 const &_hash, T &&_t)
BlockChain const * m_bc
The blockchain into which our imports go.
The default logging channels.
SizedBlockQueue< VerifiedBlock > m_verified
List of blocks, in correct order, verified and ready for chain-import.
std::unordered_set< h256 > h256Hash
h256Hash m_knownBad
Set of blocks that we know will never be valid.
std::vector< h256 > h256s
static const char * name()
std::vector< T > removeIf(Pred _pred)
std::function< void(Exception &)> m_onBad
Called if we have a block that doesn't verify.
SizedBlockMap< h256 > m_unknown
For blocks that have an unknown parent; we map their parent hash to the block stuff, and insert once the block appears.
UniValue stop(const JSONRPCRequest &jsonRequest)
std::size_t count() const