24 #include <condition_variable> 27 #include <boost/thread.hpp> 69 std::size_t
count()
const {
return m_queue.size(); }
71 std::size_t
size()
const {
return m_size; }
73 bool isEmpty()
const {
return m_queue.empty(); }
75 h256 nextHash()
const {
return m_queue.front().verified.info.sha3Uncles(); }
77 T
const&
next()
const {
return m_queue.front(); }
87 m_queue.emplace_back(std::move(_t));
88 m_size += m_queue.back().blockData.size();
96 m_size -= t.blockData.size();
103 return removeRange(m_queue.begin(), m_queue.begin() + _n);
108 std::vector<T> removed =
removeIf(sha3UnclesEquals(_hash));
109 return !removed.empty();
115 auto const removedBegin = std::remove_if(m_queue.begin(), m_queue.end(), _pred);
117 return removeRange(removedBegin, m_queue.end());
122 auto const it = std::find_if(m_queue.begin(), m_queue.end(), sha3UnclesEquals(_hash));
124 if (it == m_queue.end())
127 m_size -= it->blockData.size();
128 m_size += _t.blockData.size();
135 static std::function<bool(T const&)> sha3UnclesEquals(
h256 const& _hash)
137 return [&_hash](T
const& _t) {
return _t.verified.info.sha3Uncles() == _hash; };
140 std::vector<T> removeRange(
typename std::deque<T>::iterator _begin,
typename std::deque<T>::iterator _end)
142 std::vector<T> ret(std::make_move_iterator(_begin), std::make_move_iterator(_end));
144 for (
auto it = ret.begin(); it != ret.end(); ++it)
145 m_size -= it->blockData.size();
147 m_queue.erase(_begin, _end);
151 std::deque<T> m_queue;
152 std::atomic<size_t> m_size = {0};
155 template<
class KeyType>
159 std::size_t
count()
const {
return m_map.size(); }
161 std::size_t
size()
const {
return m_size; }
163 bool isEmpty()
const {
return m_map.empty(); }
165 KeyType
firstKey()
const {
return m_map.begin()->first; }
175 auto hashAndBlock = std::make_pair(_hash, std::move(_blockData));
176 auto keyAndValue = std::make_pair(_key, std::move(hashAndBlock));
177 m_map.insert(std::move(keyAndValue));
178 m_size += _blockData.size();
184 auto const equalRange = m_map.equal_range(_key);
185 return removeRange(equalRange.first, equalRange.second);
191 return removeRange(m_map.begin(), m_map.upper_bound(_key));
196 using BlockMultimap = std::multimap<KeyType, std::pair<h256, bytes>>;
198 std::vector<std::pair<h256, bytes>> removeRange(
typename BlockMultimap::iterator _begin,
typename BlockMultimap::iterator _end)
200 std::vector<std::pair<h256, bytes>> removed;
201 std::size_t removedSize = 0;
202 for (
auto it = _begin; it != _end; ++it)
204 removed.push_back(std::move(it->second));
205 removedSize += removed.back().second.size();
208 m_size -= removedSize;
209 m_map.erase(_begin, _end);
215 std::atomic<size_t> m_size = {0};
239 void drain(std::vector<VerifiedBlock>& o_out,
unsigned _max);
252 std::pair<unsigned, unsigned>
items()
const {
ReadGuard l(m_lock);
return std::make_pair(m_readySet.size(), m_unknownSet.size()); }
272 template <
class T>
void setOnBad(T
const& _t) { m_onBad = _t; }
280 struct UnverifiedBlock
287 void noteReady_WITH_LOCK(
h256 const& _b);
289 bool invariants()
const override;
292 void collectUnknownBad_WITH_BOTH_LOCKS(
h256 const& _bad);
293 void updateBad_WITH_LOCK(
h256 const& _bad);
294 void drainVerified_WITH_BOTH_LOCKS();
296 std::size_t knownSize()
const;
297 std::size_t knownCount()
const;
298 std::size_t unknownSize()
const;
299 std::size_t unknownCount()
const;
301 BlockChain
const* m_bc;
303 mutable boost::shared_mutex m_lock;
307 SizedBlockMap<h256> m_unknown;
309 SizedBlockMap<time_t> m_future;
312 Signal<> m_onRoomAvailable;
314 mutable Mutex m_verification;
315 std::condition_variable m_moreToVerify;
316 SizedBlockQueue<VerifiedBlock> m_verified;
317 SizedBlockQueue<VerifiedBlock> m_verifying;
318 SizedBlockQueue<UnverifiedBlock> m_unverified;
320 std::vector<std::thread> m_verifiers;
321 std::atomic<bool> m_deleting = {
false};
323 std::function<void(Exception&)> m_onBad;
325 u256 m_drainingDifficulty;
331 std::ostream&
operator<<(std::ostream& _out, BlockQueueStatus
const& _s);
Inheritable for classes that have invariants.
void drain(std::vector< VerifiedBlock > &o_out, unsigned _max)
void swap(dev::eth::Watch &_a, dev::eth::Watch &_b)
bool doneDrain(h256s const &_knownBad=h256s())
Implements the blockchain database. All data this gives is disk-backed. .
void setOnBad(T const &_t)
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...
QueueStatus blockStatus(h256 const &_h) const
Get some infomration on the given block's status regarding us.
BlockQueueStatus status() const
Get some infomration on the current status.
void stop()
Stop all activity, leaves the class in limbo, waiting for destruction.
void tick()
Notes that time has moved on and some blocks that used to be "in the future" may no be valid...
void clear()
Clear everything.
Handler onReady(std::function< void(void)> _t)
std::size_t count() const
void insert(KeyType const &_key, h256 const &_hash, bytes &&_blockData)
h256 firstUnknown() const
Return first block with an unknown parent.
std::shared_ptr< typename Signal< Args... >::HandlerAux > Handler
void retryAllUnknown()
Force a retry of all the blocks with unknown parents.
Logger createLogger(int _severity, std::string const &_channel)
std::vector< byte > bytes
std::shared_ptr< HandlerAux > add(Callback const &_h)
A queue of blocks. Sits between network or other I/O and the BlockChain. Sorts them ready for blockch...
std::vector< std::pair< h256, bytes > > removeByKeyEqual(KeyType const &_key)
boost::shared_lock< boost::shared_mutex > ReadGuard
std::vector< std::pair< h256, bytes > > removeByKeyNotGreater(KeyType const &_key)
Handler onRoomAvailable(std::function< void(void)> _t)
boost::unique_lock< boost::shared_mutex > WriteGuard
std::vector< T > dequeueMultiple(std::size_t _n)
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void > > u256
std::size_t count() const
void setChain(BlockChain const &_bc)
std::pair< unsigned, unsigned > items() const
Get information on the items queued.
bool replace(h256 const &_hash, T &&_t)
std::unordered_set< h256 > h256Hash
std::vector< h256 > h256s
std::vector< T > removeIf(Pred _pred)
boost::log::sources::severity_channel_logger<> Logger