BlockQueue.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578
  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.cpp
  15. * @author Gav Wood <i@gavwood.com>
  16. * @date 2014
  17. */
  18. #include "BlockQueue.h"
  19. #include <thread>
  20. #include <sstream>
  21. #include <libdevcore/Log.h>
  22. #include <libethcore/Exceptions.h>
  23. #include <libethcore/BlockHeader.h>
  24. #include "BlockChain.h"
  25. #include "VerifiedBlock.h"
  26. #include "State.h"
  27. using namespace std;
  28. using namespace dev;
  29. using namespace dev::eth;
  30. #if defined(_WIN32)
  31. const char* BlockQueueChannel::name() { return EthOrange "[]>"; }
  32. #else
  33. const char* BlockQueueChannel::name() { return EthOrange "▣┅▶"; }
  34. #endif
  35. const char* BlockQueueTraceChannel::name() { return EthOrange "▣ ▶"; }
  36. size_t const c_maxKnownCount = 100000;
  37. size_t const c_maxKnownSize = 128 * 1024 * 1024;
  38. size_t const c_maxUnknownCount = 100000;
  39. size_t const c_maxUnknownSize = 512 * 1024 * 1024; // Block size can be ~50kb
  40. BlockQueue::BlockQueue():
  41. m_unknownSize(0),
  42. m_knownSize(0),
  43. m_unknownCount(0),
  44. m_knownCount(0)
  45. {
  46. // Allow some room for other activity
  47. unsigned verifierThreads = std::max(thread::hardware_concurrency(), 3U) - 2U;
  48. for (unsigned i = 0; i < verifierThreads; ++i)
  49. m_verifiers.emplace_back([=](){
  50. setThreadName("verifier" + toString(i));
  51. this->verifierBody();
  52. });
  53. }
  54. BlockQueue::~BlockQueue()
  55. {
  56. stop();
  57. }
  58. void BlockQueue::stop()
  59. {
  60. DEV_GUARDED(m_verification)
  61. m_deleting = true;
  62. m_moreToVerify.notify_all();
  63. for (auto& i: m_verifiers)
  64. i.join();
  65. m_verifiers.clear();
  66. }
  67. void BlockQueue::clear()
  68. {
  69. WriteGuard l(m_lock);
  70. DEV_INVARIANT_CHECK;
  71. Guard l2(m_verification);
  72. m_readySet.clear();
  73. m_drainingSet.clear();
  74. m_verified.clear();
  75. m_unverified.clear();
  76. m_verifying.clear();
  77. m_unknownSet.clear();
  78. m_unknown.clear();
  79. m_future.clear();
  80. m_unknownSize = 0;
  81. m_unknownCount = 0;
  82. m_knownSize = 0;
  83. m_knownCount = 0;
  84. m_difficulty = 0;
  85. m_drainingDifficulty = 0;
  86. }
  87. void BlockQueue::verifierBody()
  88. {
  89. while (!m_deleting)
  90. {
  91. UnverifiedBlock work;
  92. {
  93. unique_lock<Mutex> l(m_verification);
  94. m_moreToVerify.wait(l, [&](){ return !m_unverified.empty() || m_deleting; });
  95. if (m_deleting)
  96. return;
  97. swap(work, m_unverified.front());
  98. m_unverified.pop_front();
  99. BlockHeader bi;
  100. bi.setSha3Uncles(work.hash);
  101. bi.setParentHash(work.parentHash);
  102. m_verifying.emplace_back(move(bi));
  103. }
  104. VerifiedBlock res;
  105. swap(work.block, res.blockData);
  106. try
  107. {
  108. res.verified = m_bc->verifyBlock(&res.blockData, m_onBad, ImportRequirements::OutOfOrderChecks);
  109. }
  110. catch (std::exception const& _ex)
  111. {
  112. // bad block.
  113. // has to be this order as that's how invariants() assumes.
  114. WriteGuard l2(m_lock);
  115. unique_lock<Mutex> l(m_verification);
  116. m_readySet.erase(work.hash);
  117. m_knownBad.insert(work.hash);
  118. for (auto it = m_verifying.begin(); it != m_verifying.end(); ++it)
  119. if (it->verified.info.sha3Uncles() == work.hash)
  120. {
  121. m_verifying.erase(it);
  122. goto OK1;
  123. }
  124. cwarn << "Unexpected exception when verifying block: " << _ex.what();
  125. OK1:;
  126. drainVerified_WITH_BOTH_LOCKS();
  127. continue;
  128. }
  129. bool ready = false;
  130. {
  131. WriteGuard l2(m_lock);
  132. unique_lock<Mutex> l(m_verification);
  133. if (!m_verifying.empty() && m_verifying.front().verified.info.sha3Uncles() == work.hash)
  134. {
  135. // we're next!
  136. m_verifying.pop_front();
  137. if (m_knownBad.count(res.verified.info.parentHash()))
  138. {
  139. m_readySet.erase(res.verified.info.hash());
  140. m_knownBad.insert(res.verified.info.hash());
  141. }
  142. else
  143. m_verified.emplace_back(move(res));
  144. drainVerified_WITH_BOTH_LOCKS();
  145. ready = true;
  146. }
  147. else
  148. {
  149. for (auto& i: m_verifying)
  150. if (i.verified.info.sha3Uncles() == work.hash)
  151. {
  152. i = move(res);
  153. goto OK;
  154. }
  155. cwarn << "BlockQueue missing our job: was there a GM?";
  156. OK:;
  157. }
  158. }
  159. if (ready)
  160. m_onReady();
  161. }
  162. }
  163. void BlockQueue::drainVerified_WITH_BOTH_LOCKS()
  164. {
  165. while (!m_verifying.empty() && !m_verifying.front().blockData.empty())
  166. {
  167. if (m_knownBad.count(m_verifying.front().verified.info.parentHash()))
  168. {
  169. m_readySet.erase(m_verifying.front().verified.info.hash());
  170. m_knownBad.insert(m_verifying.front().verified.info.hash());
  171. }
  172. else
  173. m_verified.emplace_back(move(m_verifying.front()));
  174. m_verifying.pop_front();
  175. }
  176. }
  177. ImportResult BlockQueue::import(bytesConstRef _block, bool _isOurs)
  178. {
  179. clog(BlockQueueTraceChannel) << std::this_thread::get_id();
  180. // Check if we already know this block.
  181. h256 h = BlockHeader::headerHashFromBlock(_block);
  182. clog(BlockQueueTraceChannel) << "Queuing block" << h << "for import...";
  183. UpgradableGuard l(m_lock);
  184. if (m_readySet.count(h) || m_drainingSet.count(h) || m_unknownSet.count(h) || m_knownBad.count(h))
  185. {
  186. // Already know about this one.
  187. clog(BlockQueueTraceChannel) << "Already known.";
  188. return ImportResult::AlreadyKnown;
  189. }
  190. BlockHeader bi;
  191. try
  192. {
  193. // TODO: quick verification of seal - will require BlockQueue to be templated on SealEngine
  194. // VERIFY: populates from the block and checks the block is internally coherent.
  195. bi = m_bc->verifyBlock(_block, m_onBad, ImportRequirements::PostGenesis).info;
  196. }
  197. catch (Exception const& _e)
  198. {
  199. cwarn << "Ignoring malformed block: " << diagnostic_information(_e);
  200. return ImportResult::Malformed;
  201. }
  202. clog(BlockQueueTraceChannel) << "Block" << h << "is" << bi.number() << "parent is" << bi.parentHash();
  203. // Check block doesn't already exist first!
  204. if (m_bc->isKnown(h))
  205. {
  206. cblockq << "Already known in chain.";
  207. return ImportResult::AlreadyInChain;
  208. }
  209. UpgradeGuard ul(l);
  210. DEV_INVARIANT_CHECK;
  211. // Check it's not in the future
  212. if (bi.timestamp() > utcTime() && !_isOurs)
  213. {
  214. m_future.insert(make_pair((unsigned)bi.timestamp(), make_pair(h, _block.toBytes())));
  215. char buf[24];
  216. time_t bit = (unsigned)bi.timestamp();
  217. if (strftime(buf, 24, "%X", localtime(&bit)) == 0)
  218. buf[0] = '\0'; // empty if case strftime fails
  219. clog(BlockQueueTraceChannel) << "OK - queued for future [" << bi.timestamp() << "vs" << utcTime() << "] - will wait until" << buf;
  220. m_unknownSize += _block.size();
  221. m_unknownCount++;
  222. m_difficulty += bi.difficulty();
  223. bool unknown = !m_readySet.count(bi.parentHash()) && !m_drainingSet.count(bi.parentHash()) && !m_bc->isKnown(bi.parentHash());
  224. return unknown ? ImportResult::FutureTimeUnknown : ImportResult::FutureTimeKnown;
  225. }
  226. else
  227. {
  228. // We now know it.
  229. if (m_knownBad.count(bi.parentHash()))
  230. {
  231. m_knownBad.insert(bi.hash());
  232. updateBad_WITH_LOCK(bi.hash());
  233. // bad parent; this is bad too, note it as such
  234. return ImportResult::BadChain;
  235. }
  236. else if (!m_readySet.count(bi.parentHash()) && !m_drainingSet.count(bi.parentHash()) && !m_bc->isKnown(bi.parentHash()))
  237. {
  238. // We don't know the parent (yet) - queue it up for later. It'll get resent to us if we find out about its ancestry later on.
  239. clog(BlockQueueTraceChannel) << "OK - queued as unknown parent:" << bi.parentHash();
  240. m_unknown.insert(make_pair(bi.parentHash(), make_pair(h, _block.toBytes())));
  241. m_unknownSet.insert(h);
  242. m_unknownSize += _block.size();
  243. m_difficulty += bi.difficulty();
  244. m_unknownCount++;
  245. return ImportResult::UnknownParent;
  246. }
  247. else
  248. {
  249. // If valid, append to blocks.
  250. clog(BlockQueueTraceChannel) << "OK - ready for chain insertion.";
  251. DEV_GUARDED(m_verification)
  252. m_unverified.push_back(UnverifiedBlock { h, bi.parentHash(), _block.toBytes() });
  253. m_moreToVerify.notify_one();
  254. m_readySet.insert(h);
  255. m_knownSize += _block.size();
  256. m_difficulty += bi.difficulty();
  257. m_knownCount++;
  258. noteReady_WITH_LOCK(h);
  259. return ImportResult::Success;
  260. }
  261. }
  262. }
  263. void BlockQueue::updateBad_WITH_LOCK(h256 const& _bad)
  264. {
  265. DEV_INVARIANT_CHECK;
  266. DEV_GUARDED(m_verification)
  267. {
  268. collectUnknownBad_WITH_BOTH_LOCKS(_bad);
  269. bool moreBad = true;
  270. while (moreBad)
  271. {
  272. moreBad = false;
  273. std::deque<VerifiedBlock> oldVerified;
  274. swap(m_verified, oldVerified);
  275. for (auto& b: oldVerified)
  276. if (m_knownBad.count(b.verified.info.parentHash()) || m_knownBad.count(b.verified.info.hash()))
  277. {
  278. m_knownBad.insert(b.verified.info.hash());
  279. m_readySet.erase(b.verified.info.hash());
  280. collectUnknownBad_WITH_BOTH_LOCKS(b.verified.info.hash());
  281. moreBad = true;
  282. }
  283. else
  284. m_verified.push_back(std::move(b));
  285. std::deque<UnverifiedBlock> oldUnverified;
  286. swap(m_unverified, oldUnverified);
  287. for (auto& b: oldUnverified)
  288. if (m_knownBad.count(b.parentHash) || m_knownBad.count(b.hash))
  289. {
  290. m_knownBad.insert(b.hash);
  291. m_readySet.erase(b.hash);
  292. collectUnknownBad_WITH_BOTH_LOCKS(b.hash);
  293. moreBad = true;
  294. }
  295. else
  296. m_unverified.push_back(std::move(b));
  297. std::deque<VerifiedBlock> oldVerifying;
  298. swap(m_verifying, oldVerifying);
  299. for (auto& b: oldVerifying)
  300. if (m_knownBad.count(b.verified.info.parentHash()) || m_knownBad.count(b.verified.info.sha3Uncles()))
  301. {
  302. h256 const& h = b.blockData.size() != 0 ? b.verified.info.hash() : b.verified.info.sha3Uncles();
  303. m_knownBad.insert(h);
  304. m_readySet.erase(h);
  305. collectUnknownBad_WITH_BOTH_LOCKS(h);
  306. moreBad = true;
  307. }
  308. else
  309. m_verifying.push_back(std::move(b));
  310. }
  311. }
  312. }
  313. void BlockQueue::collectUnknownBad_WITH_BOTH_LOCKS(h256 const& _bad)
  314. {
  315. list<h256> badQueue(1, _bad);
  316. while (!badQueue.empty())
  317. {
  318. auto r = m_unknown.equal_range(badQueue.front());
  319. badQueue.pop_front();
  320. for (auto it = r.first; it != r.second; ++it)
  321. {
  322. m_unknownSize -= it->second.second.size();
  323. m_unknownCount--;
  324. auto newBad = it->second.first;
  325. m_unknownSet.erase(newBad);
  326. m_knownBad.insert(newBad);
  327. badQueue.push_back(newBad);
  328. }
  329. m_unknown.erase(r.first, r.second);
  330. }
  331. }
  332. bool BlockQueue::doneDrain(h256s const& _bad)
  333. {
  334. WriteGuard l(m_lock);
  335. DEV_INVARIANT_CHECK;
  336. m_drainingSet.clear();
  337. m_difficulty -= m_drainingDifficulty;
  338. m_drainingDifficulty = 0;
  339. if (_bad.size())
  340. {
  341. // at least one of them was bad.
  342. m_knownBad += _bad;
  343. for (h256 const& b: _bad)
  344. updateBad_WITH_LOCK(b);
  345. }
  346. return !m_readySet.empty();
  347. }
  348. void BlockQueue::tick()
  349. {
  350. vector<pair<h256, bytes>> todo;
  351. {
  352. UpgradableGuard l(m_lock);
  353. if (m_future.empty())
  354. return;
  355. cblockq << "Checking past-future blocks...";
  356. uint64_t t = utcTime();
  357. if (t < m_future.begin()->first)
  358. return;
  359. cblockq << "Past-future blocks ready.";
  360. {
  361. UpgradeGuard l2(l);
  362. DEV_INVARIANT_CHECK;
  363. auto end = m_future.upper_bound(t);
  364. for (auto i = m_future.begin(); i != end; ++i)
  365. {
  366. m_unknownSize -= i->second.second.size();
  367. m_unknownCount--;
  368. todo.push_back(move(i->second));
  369. }
  370. m_future.erase(m_future.begin(), end);
  371. }
  372. }
  373. cblockq << "Importing" << todo.size() << "past-future blocks.";
  374. for (auto const& b: todo)
  375. import(&b.second);
  376. }
  377. template <class T> T advanced(T _t, unsigned _n)
  378. {
  379. std::advance(_t, _n);
  380. return _t;
  381. }
  382. QueueStatus BlockQueue::blockStatus(h256 const& _h) const
  383. {
  384. ReadGuard l(m_lock);
  385. return
  386. m_readySet.count(_h) ?
  387. QueueStatus::Ready :
  388. m_drainingSet.count(_h) ?
  389. QueueStatus::Importing :
  390. m_unknownSet.count(_h) ?
  391. QueueStatus::UnknownParent :
  392. m_knownBad.count(_h) ?
  393. QueueStatus::Bad :
  394. QueueStatus::Unknown;
  395. }
  396. bool BlockQueue::knownFull() const
  397. {
  398. return m_knownSize > c_maxKnownSize || m_knownCount > c_maxKnownCount;
  399. }
  400. bool BlockQueue::unknownFull() const
  401. {
  402. return m_unknownSize > c_maxUnknownSize || m_unknownCount > c_maxUnknownCount;
  403. }
  404. void BlockQueue::drain(VerifiedBlocks& o_out, unsigned _max)
  405. {
  406. bool wasFull = false;
  407. DEV_WRITE_GUARDED(m_lock)
  408. {
  409. DEV_INVARIANT_CHECK;
  410. wasFull = knownFull();
  411. if (m_drainingSet.empty())
  412. {
  413. m_drainingDifficulty = 0;
  414. DEV_GUARDED(m_verification)
  415. {
  416. o_out.resize(min<unsigned>(_max, m_verified.size()));
  417. for (unsigned i = 0; i < o_out.size(); ++i)
  418. swap(o_out[i], m_verified[i]);
  419. m_verified.erase(m_verified.begin(), advanced(m_verified.begin(), o_out.size()));
  420. }
  421. for (auto const& bs: o_out)
  422. {
  423. // TODO: @optimise use map<h256, bytes> rather than vector<bytes> & set<h256>.
  424. auto h = bs.verified.info.hash();
  425. m_drainingSet.insert(h);
  426. m_drainingDifficulty += bs.verified.info.difficulty();
  427. m_readySet.erase(h);
  428. m_knownSize -= bs.verified.block.size();
  429. m_knownCount--;
  430. }
  431. }
  432. }
  433. if (wasFull && !knownFull())
  434. m_onRoomAvailable();
  435. }
  436. bool BlockQueue::invariants() const
  437. {
  438. Guard l(m_verification);
  439. if (!(m_readySet.size() == m_verified.size() + m_unverified.size() + m_verifying.size()))
  440. {
  441. std::stringstream s;
  442. s << "Failed BlockQueue invariant: m_readySet: " << m_readySet.size() << " m_verified: " << m_verified.size() << " m_unverified: " << m_unverified.size() << " m_verifying" << m_verifying.size();
  443. BOOST_THROW_EXCEPTION(FailedInvariant() << errinfo_comment(s.str()));
  444. }
  445. return true;
  446. }
  447. void BlockQueue::noteReady_WITH_LOCK(h256 const& _good)
  448. {
  449. DEV_INVARIANT_CHECK;
  450. list<h256> goodQueue(1, _good);
  451. bool notify = false;
  452. while (!goodQueue.empty())
  453. {
  454. auto r = m_unknown.equal_range(goodQueue.front());
  455. goodQueue.pop_front();
  456. for (auto it = r.first; it != r.second; ++it)
  457. {
  458. DEV_GUARDED(m_verification)
  459. m_unverified.push_back(UnverifiedBlock { it->second.first, it->first, it->second.second });
  460. m_knownSize += it->second.second.size();
  461. m_knownCount++;
  462. m_unknownSize -= it->second.second.size();
  463. m_unknownCount--;
  464. auto newReady = it->second.first;
  465. m_unknownSet.erase(newReady);
  466. m_readySet.insert(newReady);
  467. goodQueue.push_back(newReady);
  468. notify = true;
  469. }
  470. m_unknown.erase(r.first, r.second);
  471. }
  472. if (notify)
  473. m_moreToVerify.notify_all();
  474. }
  475. void BlockQueue::retryAllUnknown()
  476. {
  477. WriteGuard l(m_lock);
  478. DEV_INVARIANT_CHECK;
  479. for (auto it = m_unknown.begin(); it != m_unknown.end(); ++it)
  480. {
  481. DEV_GUARDED(m_verification)
  482. m_unverified.push_back(UnverifiedBlock { it->second.first, it->first, it->second.second });
  483. auto newReady = it->second.first;
  484. m_unknownSet.erase(newReady);
  485. m_readySet.insert(newReady);
  486. m_knownCount++;
  487. m_moreToVerify.notify_one();
  488. }
  489. m_unknown.clear();
  490. m_knownSize += m_unknownSize;
  491. m_unknownSize = 0;
  492. m_unknownCount = 0;
  493. m_moreToVerify.notify_all();
  494. }
  495. std::ostream& dev::eth::operator<<(std::ostream& _out, BlockQueueStatus const& _bqs)
  496. {
  497. _out << "importing: " << _bqs.importing << endl;
  498. _out << "verified: " << _bqs.verified << endl;
  499. _out << "verifying: " << _bqs.verifying << endl;
  500. _out << "unverified: " << _bqs.unverified << endl;
  501. _out << "future: " << _bqs.future << endl;
  502. _out << "unknown: " << _bqs.unknown << endl;
  503. _out << "bad: " << _bqs.bad << endl;
  504. return _out;
  505. }
  506. u256 BlockQueue::difficulty() const
  507. {
  508. UpgradableGuard l(m_lock);
  509. return m_difficulty;
  510. }
  511. bool BlockQueue::isActive() const
  512. {
  513. UpgradableGuard l(m_lock);
  514. if (m_readySet.empty() && m_drainingSet.empty())
  515. DEV_GUARDED(m_verification)
  516. if (m_verified.empty() && m_verifying.empty() && m_unverified.empty())
  517. return false;
  518. return true;
  519. }
  520. std::ostream& dev::eth::operator<< (std::ostream& os, QueueStatus const& obj)
  521. {
  522. os << static_cast<std::underlying_type<QueueStatus>::type>(obj);
  523. return os;
  524. }