Ethereum  PoC-8
The C++ Implementation of Ethereum
BlockChain.cpp
Go to the documentation of this file.
1 /*
2  This file is part of cpp-ethereum.
3 
4  cpp-ethereum is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  cpp-ethereum is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
16 */
22 #include "BlockChain.h"
23 
24 #include "Block.h"
25 #include "GenesisInfo.h"
27 #include "State.h"
28 #include <libdevcore/Assertions.h>
29 #include <libdevcore/Common.h>
30 #include <libdevcore/DBFactory.h>
31 #include <libdevcore/FileSystem.h>
32 #include <libdevcore/FixedHash.h>
33 #include <libdevcore/RLP.h>
34 #include <libdevcore/TrieHash.h>
35 #include <libethcore/BlockHeader.h>
36 #include <libethcore/Exceptions.h>
37 
38 #include <boost/exception/errinfo_nested_exception.hpp>
39 #include <boost/filesystem.hpp>
40 
41 using namespace std;
42 using namespace dev;
43 using namespace dev::eth;
44 namespace fs = boost::filesystem;
45 
46 #define ETH_TIMED_IMPORTS 1
47 
48 namespace
49 {
50 std::string const c_chainStart{"chainStart"};
51 db::Slice const c_sliceChainStart{c_chainStart};
52 }
53 
54 std::ostream& dev::eth::operator<<(std::ostream& _out, BlockChain const& _bc)
55 {
56  string cmp = toBigEndianString(_bc.currentHash());
57  _bc.m_blocksDB->forEach([&_out, &cmp](db::Slice const& _key, db::Slice const& _value) {
58  if (string(_key.data(), _key.size()) != "best")
59  {
60  const string key(_key.data(), _key.size());
61  try
62  {
63  BlockHeader d(bytesConstRef{_value});
64  _out << toHex(key) << ": " << d.number() << " @ " << d.parentHash()
65  << (cmp == key ? " BEST" : "") << std::endl;
66  }
67  catch (...)
68  {
69  cwarn << "Invalid DB entry:" << toHex(key) << " -> "
70  << toHex(bytesConstRef(_value));
71  }
72  }
73  return true;
74  });
75  return _out;
76 }
77 
78 db::Slice dev::eth::toSlice(h256 const& _h, unsigned _sub)
79 {
80 #if ALL_COMPILERS_ARE_CPP11_COMPLIANT
81  static thread_local FixedHash<33> h = _h;
82  h[32] = (uint8_t)_sub;
83  return (db::Slice)h.ref();
84 #else
85  static boost::thread_specific_ptr<FixedHash<33>> t_h;
86  if (!t_h.get())
87  t_h.reset(new FixedHash<33>);
88  *t_h = FixedHash<33>(_h);
89  (*t_h)[32] = (uint8_t)_sub;
90  return (db::Slice)t_h->ref();
91 #endif //ALL_COMPILERS_ARE_CPP11_COMPLIANT
92 }
93 
94 db::Slice dev::eth::toSlice(uint64_t _n, unsigned _sub)
95 {
96 #if ALL_COMPILERS_ARE_CPP11_COMPLIANT
97  static thread_local FixedHash<33> h;
98  toBigEndian(_n, bytesRef(h.data() + 24, 8));
99  h[32] = (uint8_t)_sub;
100  return (db::Slice)h.ref();
101 #else
102  static boost::thread_specific_ptr<FixedHash<33>> t_h;
103  if (!t_h.get())
104  t_h.reset(new FixedHash<33>);
105  bytesRef ref(t_h->data() + 24, 8);
106  toBigEndian(_n, ref);
107  (*t_h)[32] = (uint8_t)_sub;
108  return (db::Slice)t_h->ref();
109 #endif
110 }
111 
112 namespace
113 {
114 
115 class LastBlockHashes: public LastBlockHashesFace
116 {
117 public:
118  explicit LastBlockHashes(BlockChain const& _bc): m_bc(_bc) {}
119 
120  h256s precedingHashes(h256 const& _mostRecentHash) const override
121  {
122  Guard l(m_lastHashesMutex);
123  if (m_lastHashes.empty() || m_lastHashes.front() != _mostRecentHash)
124  {
125  m_lastHashes.resize(256);
126  m_lastHashes[0] = _mostRecentHash;
127  for (unsigned i = 0; i < 255; ++i)
128  m_lastHashes[i + 1] = m_lastHashes[i] ? m_bc.info(m_lastHashes[i]).parentHash() : h256();
129  }
130  return m_lastHashes;
131  }
132 
133  void clear() override
134  {
135  Guard l(m_lastHashesMutex);
136  m_lastHashes.clear();
137  }
138 
139 private:
140  BlockChain const& m_bc;
141 
142  mutable Mutex m_lastHashesMutex;
143  mutable h256s m_lastHashes;
144 };
145 
146 void addBlockInfo(Exception& io_ex, BlockHeader const& _header, bytes&& _blockData)
147 {
148  io_ex << errinfo_now(time(0));
149  io_ex << errinfo_block(std::move(_blockData));
150  // only populate extraData if we actually managed to extract it. otherwise,
151  // we might be clobbering the existing one.
152  if (!_header.extraData().empty())
153  io_ex << errinfo_extraData(_header.extraData());
154 }
155 
156 }
157 
158 
160 static const chrono::system_clock::duration c_collectionDuration = chrono::seconds(60);
161 
163 static const unsigned c_collectionQueueSize = 20;
164 
166 static const unsigned c_maxCacheSize = 1024 * 1024 * 64;
167 
169 static const unsigned c_minCacheSize = 1024 * 1024 * 32;
170 
171 
172 BlockChain::BlockChain(ChainParams const& _p, fs::path const& _dbPath, WithExisting _we, ProgressCallback const& _pc):
173  m_lastBlockHashes(new LastBlockHashes(*this)),
174  m_dbPath(_dbPath)
175 {
176  init(_p);
177  open(_dbPath, _we, _pc);
178 }
179 
181 {
182  close();
183 }
184 
186 {
187  UpgradableGuard l(x_genesis);
188  if (!m_genesis)
189  {
190  auto gb = m_params.genesisBlock();
191  UpgradeGuard ul(l);
192  m_genesis = BlockHeader(gb);
193  m_genesisHeaderBytes = BlockHeader::extractHeader(&gb).data().toBytes();
194  m_genesisHash = m_genesis.hash();
195  }
196  return m_genesis;
197 }
198 
199 void BlockChain::init(ChainParams const& _p)
200 {
201  // initialise deathrow.
202  m_cacheUsage.resize(c_collectionQueueSize);
203  m_lastCollection = chrono::system_clock::now();
204 
205  // Initialise with the genesis as the last block on the longest chain.
206  m_params = _p;
207  m_sealEngine.reset(m_params.createSealEngine());
208  m_genesis.clear();
209  genesis();
210 }
211 
212 unsigned BlockChain::open(fs::path const& _path, WithExisting _we)
213 {
214  fs::path path = _path.empty() ? db::databasePath() : _path;
215  fs::path chainPath = path / fs::path(toHex(m_genesisHash.ref().cropped(0, 4)));
216  fs::path extrasPath = chainPath / fs::path(toString(c_databaseVersion));
217  unsigned lastMinor = c_minorProtocolVersion;
218 
219  if (db::isDiskDatabase())
220  {
221  fs::create_directories(extrasPath);
222  DEV_IGNORE_EXCEPTIONS(fs::permissions(extrasPath, fs::owner_all));
223 
224  bytes status = contents(extrasPath / fs::path("minor"));
225  if (!status.empty())
226  DEV_IGNORE_EXCEPTIONS(lastMinor = (unsigned)RLP(status));
227  if (c_minorProtocolVersion != lastMinor)
228  {
229  cnote << "Killing extras database (DB minor version:" << lastMinor << " != our miner version: " << c_minorProtocolVersion << ").";
230  DEV_IGNORE_EXCEPTIONS(fs::remove_all(extrasPath / fs::path("details.old")));
231  fs::rename(extrasPath / fs::path("extras"), extrasPath / fs::path("extras.old"));
232  fs::remove_all(extrasPath / fs::path("state"));
233  writeFile(extrasPath / fs::path("minor"), rlp(c_minorProtocolVersion));
234  lastMinor = (unsigned)RLP(status);
235  }
236 
237  if (_we == WithExisting::Kill)
238  {
239  cnote << "Killing blockchain & extras database (WithExisting::Kill).";
240  fs::remove_all(chainPath / fs::path("blocks"));
241  fs::remove_all(extrasPath / fs::path("extras"));
242  }
243  }
244 
245  try
246  {
247  m_blocksDB = db::DBFactory::create(chainPath / fs::path("blocks"));
248  m_extrasDB = db::DBFactory::create(extrasPath / fs::path("extras"));
249  }
250  catch (db::DatabaseError const& ex)
251  {
252  // Check the exact reason of errror, in case of IOError we can display user-friendly message
253  if (*boost::get_error_info<db::errinfo_dbStatusCode>(ex) != db::DatabaseStatus::IOError)
254  throw;
255 
256  if (db::isDiskDatabase())
257  {
258  if (fs::space(chainPath / fs::path("blocks")).available < 1024)
259  {
260  cwarn << "Not enough available space found on hard drive. Please free some up and then re-run. Bailing.";
261  BOOST_THROW_EXCEPTION(NotEnoughAvailableSpace());
262  }
263  else
264  {
265  cwarn <<
266  "Database " <<
267  (chainPath / fs::path("blocks")) <<
268  "or " <<
269  (extrasPath / fs::path("extras")) <<
270  "already open. You appear to have another instance of ethereum running. Bailing.";
271  BOOST_THROW_EXCEPTION(DatabaseAlreadyOpen());
272  }
273  }
274  else
275  {
276  cwarn << "Unknown database error occurred during in-memory database creation";
277  throw;
278  }
279  }
280 
281  if (_we != WithExisting::Verify && !details(m_genesisHash))
282  {
283  BlockHeader gb(m_params.genesisBlock());
284  // Insert details of genesis block.
285  m_details[m_genesisHash] = BlockDetails(0, gb.difficulty(), h256(), {});
286  auto r = m_details[m_genesisHash].rlp();
287  m_extrasDB->insert(toSlice(m_genesisHash, ExtraDetails), (db::Slice)dev::ref(r));
288  assert(isKnown(gb.hash()));
289  }
290 
291 #if ETH_PARANOIA
292  checkConsistency();
293 #endif
294 
295  // TODO: Implement ability to rebuild details map from DB.
296  auto const l = m_extrasDB->lookup(db::Slice("best"));
297  m_lastBlockHash = l.empty() ? m_genesisHash : h256(l, h256::FromBinary);
298 
299  m_lastBlockNumber = number(m_lastBlockHash);
300 
301  ctrace << "Opened blockchain DB. Latest: " << currentHash() << (lastMinor == c_minorProtocolVersion ? "(rebuild not needed)" : "*** REBUILD NEEDED ***");
302  return lastMinor;
303 }
304 
305 void BlockChain::open(fs::path const& _path, WithExisting _we, ProgressCallback const& _pc)
306 {
307  if (open(_path, _we) != c_minorProtocolVersion || _we == WithExisting::Verify)
308  rebuild(_path, _pc);
309 }
310 
312 {
313  close();
314  init(_p);
315  open(m_dbPath, _we, _pc);
316 }
317 
318 void BlockChain::close()
319 {
320  ctrace << "Closing blockchain DB";
321  // Not thread safe...
322  m_extrasDB.reset();
323  m_blocksDB.reset();
324  DEV_WRITE_GUARDED(x_lastBlockHash)
325  {
326  m_lastBlockHash = m_genesisHash;
327  m_lastBlockNumber = 0;
328  }
329  m_details.clear();
330  m_blocks.clear();
331  m_logBlooms.clear();
332  m_receipts.clear();
333  m_transactionAddresses.clear();
334  m_blockHashes.clear();
335  m_blocksBlooms.clear();
336  m_cacheUsage.clear();
337  m_inUse.clear();
338  m_lastBlockHashes->clear();
339 }
340 
341 void BlockChain::rebuild(fs::path const& _path, std::function<void(unsigned, unsigned)> const& _progress)
342 {
343  if (!db::isDiskDatabase())
344  {
345  cwarn <<"In-memory database detected, skipping rebuild (since there's no existing database to rebuild)";
346  return;
347  }
348 
349  fs::path path = _path.empty() ? db::databasePath() : _path;
350  fs::path chainPath = path / fs::path(toHex(m_genesisHash.ref().cropped(0, 4)));
351  fs::path extrasPath = chainPath / fs::path(toString(c_databaseVersion));
352 
353  unsigned originalNumber = m_lastBlockNumber;
354 
356  // TODO
357  // - KILL ALL STATE/CHAIN
358  // - REINSERT ALL BLOCKS
360 
361  // Keep extras DB around, but under a temp name
362  m_extrasDB.reset();
363  fs::rename(extrasPath / fs::path("extras"), extrasPath / fs::path("extras.old"));
364  std::unique_ptr<db::DatabaseFace> oldExtrasDB(db::DBFactory::create(extrasPath / fs::path("extras.old")));
365  m_extrasDB = db::DBFactory::create(extrasPath / fs::path("extras"));
366 
367  // Open a fresh state DB
368  Block s = genesisBlock(State::openDB(path.string(), m_genesisHash, WithExisting::Kill));
369 
370  // Clear all memos ready for replay.
371  m_details.clear();
372  m_logBlooms.clear();
373  m_receipts.clear();
374  m_transactionAddresses.clear();
375  m_blockHashes.clear();
376  m_blocksBlooms.clear();
377  m_lastBlockHashes->clear();
378  m_lastBlockHash = genesisHash();
379  m_lastBlockNumber = 0;
380 
381  m_details[m_lastBlockHash].totalDifficulty = s.info().difficulty();
382 
383  m_extrasDB->insert(toSlice(m_lastBlockHash, ExtraDetails),
384  (db::Slice)dev::ref(m_details[m_lastBlockHash].rlp()));
385 
386  h256 lastHash = m_lastBlockHash;
387  Timer t;
388  for (unsigned d = 1; d <= originalNumber; ++d)
389  {
390  if (!(d % 1000))
391  {
392  cerr << "\n1000 blocks in " << t.elapsed() << "s = " << (1000.0 / t.elapsed()) << "b/s" << endl;
393  t.restart();
394  }
395  try
396  {
397  bytes b = block(queryExtras<BlockHash, uint64_t, ExtraBlockHash>(
398  d, m_blockHashes, x_blockHashes, NullBlockHash, oldExtrasDB.get())
399  .value);
400 
401  BlockHeader bi(&b);
402 
403  if (bi.parentHash() != lastHash)
404  {
405  cwarn << "DISJOINT CHAIN DETECTED; " << bi.hash() << "#" << d << " -> parent is" << bi.parentHash() << "; expected" << lastHash << "#" << (d - 1);
406  return;
407  }
408  lastHash = bi.hash();
409  import(b, s.db(), 0);
410  }
411  catch (...)
412  {
413  // Failed to import - stop here.
414  break;
415  }
416 
417  if (_progress)
418  _progress(d, originalNumber);
419  }
420 
421  fs::remove_all(path / fs::path("extras.old"));
422 }
423 
425 {
426  ostringstream oss;
427  oss << m_lastBlockHash << '\n';
428 
429  // We need to first insert the db data into an ordered map so that the string returned from this function
430  // always has data in the same order, regardless of the underlying database implementation
431  std::map<std::string, std::string> dbData;
432  m_extrasDB->forEach([&dbData](db::Slice key, db::Slice value) {
433  dbData[key.toString()] = value.toString();
434  return true;
435  });
436 
437  for (auto const& it : dbData)
438  oss << toHex(it.first) << "/" << toHex(it.second) << '\n';
439 
440  return oss.str();
441 }
442 
443 tuple<ImportRoute, bool, unsigned> BlockChain::sync(BlockQueue& _bq, OverlayDB const& _stateDB, unsigned _max)
444 {
445 // _bq.tick(*this);
446 
447  VerifiedBlocks blocks;
448  _bq.drain(blocks, _max);
449 
450  h256s fresh;
451  h256s dead;
452  h256s badBlocks;
453  Transactions goodTransactions;
454  unsigned count = 0;
455  for (VerifiedBlock const& block: blocks)
456  {
457  do {
458  try
459  {
460  // Nonce & uncle nonces already verified in verification thread at this point.
461  ImportRoute r;
462  DEV_TIMED_ABOVE("Block import " + toString(block.verified.info.number()), 500)
463  r = import(block.verified, _stateDB, (ImportRequirements::Everything & ~ImportRequirements::ValidSeal & ~ImportRequirements::CheckUncles) != 0);
464  fresh += r.liveBlocks;
465  dead += r.deadBlocks;
466  goodTransactions.reserve(goodTransactions.size() + r.goodTranactions.size());
467  std::move(std::begin(r.goodTranactions), std::end(r.goodTranactions), std::back_inserter(goodTransactions));
468  ++count;
469  }
470  catch (dev::eth::AlreadyHaveBlock const&)
471  {
472  cwarn << "ODD: Import queue contains already imported block";
473  continue;
474  }
475  catch (dev::eth::UnknownParent const&)
476  {
477  cwarn << "ODD: Import queue contains block with unknown parent.";// << LogTag::Error << boost::current_exception_diagnostic_information();
478  // NOTE: don't reimport since the queue should guarantee everything in the right order.
479  // Can't continue - chain bad.
480  badBlocks.push_back(block.verified.info.hash());
481  }
482  catch (dev::eth::FutureTime const&)
483  {
484  cwarn << "ODD: Import queue contains a block with future time.";
485  this_thread::sleep_for(chrono::seconds(1));
486  continue;
487  }
488  catch (dev::eth::TransientError const&)
489  {
490  this_thread::sleep_for(chrono::milliseconds(100));
491  continue;
492  }
493  catch (Exception& ex)
494  {
495 // cnote << "Exception while importing block. Someone (Jeff? That you?) seems to be giving us dodgy blocks!";// << LogTag::Error << diagnostic_information(ex);
496  if (m_onBad)
497  m_onBad(ex);
498  // NOTE: don't reimport since the queue should guarantee everything in the right order.
499  // Can't continue - chain bad.
500  badBlocks.push_back(block.verified.info.hash());
501  }
502  } while (false);
503  }
504  return make_tuple(ImportRoute{dead, fresh, goodTransactions}, _bq.doneDrain(badBlocks), count);
505 }
506 
507 pair<ImportResult, ImportRoute> BlockChain::attemptImport(bytes const& _block, OverlayDB const& _stateDB, bool _mustBeNew) noexcept
508 {
509  try
510  {
511  return make_pair(ImportResult::Success, import(verifyBlock(&_block, m_onBad, ImportRequirements::OutOfOrderChecks), _stateDB, _mustBeNew));
512  }
513  catch (UnknownParent&)
514  {
515  return make_pair(ImportResult::UnknownParent, ImportRoute());
516  }
517  catch (AlreadyHaveBlock&)
518  {
519  return make_pair(ImportResult::AlreadyKnown, ImportRoute());
520  }
521  catch (FutureTime&)
522  {
523  return make_pair(ImportResult::FutureTimeKnown, ImportRoute());
524  }
525  catch (Exception& ex)
526  {
527  if (m_onBad)
528  m_onBad(ex);
529  return make_pair(ImportResult::Malformed, ImportRoute());
530  }
531 }
532 
533 ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, bool _mustBeNew)
534 {
535  // VERIFY: populates from the block and checks the block is internally coherent.
537  return import(block, _db, _mustBeNew);
538 }
539 
540 void BlockChain::insert(bytes const& _block, bytesConstRef _receipts, bool _mustBeNew)
541 {
542  // VERIFY: populates from the block and checks the block is internally coherent.
544  insert(block, _receipts, _mustBeNew);
545 }
546 
547 void BlockChain::insert(VerifiedBlockRef _block, bytesConstRef _receipts, bool _mustBeNew)
548 {
549  // Check block doesn't already exist first!
550  if (_mustBeNew)
551  checkBlockIsNew(_block);
552 
553  // Work out its number as the parent's number + 1
554  if (!isKnown(_block.info.parentHash(), false))
555  {
556  LOG(m_logger) << _block.info.hash() << " : Unknown parent " << _block.info.parentHash();
557  // We don't know the parent (yet) - discard for now. It'll get resent to us if we find out about its ancestry later on.
558  BOOST_THROW_EXCEPTION(UnknownParent());
559  }
560 
561  // Check receipts
562  vector<bytesConstRef> receipts;
563  for (auto i: RLP(_receipts))
564  receipts.push_back(i.data());
565  h256 receiptsRoot = orderedTrieRoot(receipts);
566  if (_block.info.receiptsRoot() != receiptsRoot)
567  {
568  LOG(m_logger) << _block.info.hash() << " : Invalid receipts root "
569  << _block.info.receiptsRoot() << " not " << receiptsRoot;
570  // We don't know the parent (yet) - discard for now. It'll get resent to us if we find out about its ancestry later on.
571  BOOST_THROW_EXCEPTION(InvalidReceiptsStateRoot());
572  }
573 
574  auto pd = details(_block.info.parentHash());
575  if (!pd)
576  {
577  auto pdata = pd.rlp();
578  LOG(m_loggerError) << "Details is returning false despite block known: " << RLP(pdata);
579  auto parentBlock = block(_block.info.parentHash());
580  LOG(m_loggerError) << "isKnown: " << isKnown(_block.info.parentHash());
581  LOG(m_loggerError) << "last/number: " << m_lastBlockNumber << " " << m_lastBlockHash << " "
582  << _block.info.number();
583  LOG(m_loggerError) << "Block: " << BlockHeader(&parentBlock);
584  LOG(m_loggerError) << "RLP: " << RLP(parentBlock);
585  LOG(m_loggerError) << "DATABASE CORRUPTION: CRITICAL FAILURE";
586  exit(-1);
587  }
588 
589  // Check it's not crazy
590  checkBlockTimestamp(_block.info);
591 
592  // Verify parent-critical parts
594 
595  // OK - we're happy. Insert into database.
596  std::unique_ptr<db::WriteBatchFace> blocksWriteBatch = m_blocksDB->createWriteBatch();
597  std::unique_ptr<db::WriteBatchFace> extrasWriteBatch = m_extrasDB->createWriteBatch();
598 
599  BlockLogBlooms blb;
600  for (auto i: RLP(_receipts))
601  blb.blooms.push_back(TransactionReceipt(i.data()).bloom());
602 
603  // ensure parent is cached for later addition.
604  // TODO: this is a bit horrible would be better refactored into an enveloping UpgradableGuard
605  // together with an "ensureCachedWithUpdatableLock(l)" method.
606  // This is safe in practice since the caches don't get flushed nearly often enough to be
607  // done here.
608  details(_block.info.parentHash());
609  DEV_WRITE_GUARDED(x_details)
610  {
611  if (!dev::contains(m_details[_block.info.parentHash()].children, _block.info.hash()))
612  m_details[_block.info.parentHash()].children.push_back(_block.info.hash());
613  }
614 
615  blocksWriteBatch->insert(toSlice(_block.info.hash()), db::Slice(_block.block));
616  DEV_READ_GUARDED(x_details)
617  extrasWriteBatch->insert(toSlice(_block.info.parentHash(), ExtraDetails),
618  (db::Slice)dev::ref(m_details[_block.info.parentHash()].rlp()));
619 
620  BlockDetails bd((unsigned)pd.number + 1, pd.totalDifficulty + _block.info.difficulty(), _block.info.parentHash(), {});
621  extrasWriteBatch->insert(
622  toSlice(_block.info.hash(), ExtraDetails), (db::Slice)dev::ref(bd.rlp()));
623  extrasWriteBatch->insert(
624  toSlice(_block.info.hash(), ExtraLogBlooms), (db::Slice)dev::ref(blb.rlp()));
625  extrasWriteBatch->insert(toSlice(_block.info.hash(), ExtraReceipts), (db::Slice)_receipts);
626 
627  try
628  {
629  m_blocksDB->commit(std::move(blocksWriteBatch));
630  }
631  catch (boost::exception const& ex)
632  {
633  cwarn << "Error writing to blockchain database: " << boost::diagnostic_information(ex);
634  cwarn << "Fail writing to blockchain database. Bombing out.";
635  exit(-1);
636  }
637 
638  try
639  {
640  m_extrasDB->commit(std::move(extrasWriteBatch));
641  }
642  catch (boost::exception const& ex)
643  {
644  cwarn << "Error writing to extras database: " << boost::diagnostic_information(ex);
645  cwarn << "Fail writing to extras database. Bombing out.";
646  exit(-1);
647  }
648 }
649 
650 ImportRoute BlockChain::import(VerifiedBlockRef const& _block, OverlayDB const& _db, bool _mustBeNew)
651 {
652  //@tidy This is a behemoth of a method - could do to be split into a few smaller ones.
653 
654  ImportPerformanceLogger performanceLogger;
655 
656  // Check block doesn't already exist first!
657  if (_mustBeNew)
658  checkBlockIsNew(_block);
659 
660  // Work out its number as the parent's number + 1
661  if (!isKnown(_block.info.parentHash(), false)) // doesn't have to be current.
662  {
663  LOG(m_logger) << _block.info.hash() << " : Unknown parent " << _block.info.parentHash();
664  // We don't know the parent (yet) - discard for now. It'll get resent to us if we find out about its ancestry later on.
665  BOOST_THROW_EXCEPTION(UnknownParent() << errinfo_hash256(_block.info.parentHash()));
666  }
667 
668  auto pd = details(_block.info.parentHash());
669  if (!pd)
670  {
671  auto pdata = pd.rlp();
672  LOG(m_loggerError) << "Details is returning false despite block known: " << RLP(pdata);
673  auto parentBlock = block(_block.info.parentHash());
674  LOG(m_loggerError) << "isKnown: " << isKnown(_block.info.parentHash());
675  LOG(m_loggerError) << "last/number: " << m_lastBlockNumber << " " << m_lastBlockHash << " "
676  << _block.info.number();
677  LOG(m_loggerError) << "Block: " << BlockHeader(&parentBlock);
678  LOG(m_loggerError) << "RLP: " << RLP(parentBlock);
679  LOG(m_loggerError) << "DATABASE CORRUPTION: CRITICAL FAILURE";
680  exit(-1);
681  }
682 
683  checkBlockTimestamp(_block.info);
684 
685  // Verify parent-critical parts
687 
688  LOG(m_loggerDetail) << "Attempting import of " << _block.info.hash() << " ...";
689 
690  performanceLogger.onStageFinished("preliminaryChecks");
691 
692  BlockReceipts br;
693  u256 td;
694  try
695  {
696  // Check transactions are valid and that they result in a state equivalent to our state_root.
697  // Get total difficulty increase and update state, checking it.
698  Block s(*this, _db);
699  auto tdIncrease = s.enactOn(_block, *this);
700 
701  for (unsigned i = 0; i < s.pending().size(); ++i)
702  br.receipts.push_back(s.receipt(i));
703 
704  s.cleanup();
705 
706  td = pd.totalDifficulty + tdIncrease;
707 
708  performanceLogger.onStageFinished("enactment");
709 
710 #if ETH_PARANOIA
711  checkConsistency();
712 #endif // ETH_PARANOIA
713  }
714  catch (BadRoot& ex)
715  {
716  cwarn << "*** BadRoot error! Trying to import" << _block.info.hash() << "needed root"
717  << *boost::get_error_info<errinfo_hash256>(ex);
718  cwarn << _block.info;
719  // Attempt in import later.
720  BOOST_THROW_EXCEPTION(TransientError());
721  }
722  catch (Exception& ex)
723  {
724  addBlockInfo(ex, _block.info, _block.block.toBytes());
725  throw;
726  }
727 
728  // All ok - insert into DB
729  bytes const receipts = br.rlp();
730  return insertBlockAndExtras(_block, ref(receipts), td, performanceLogger);
731 }
732 
733 ImportRoute BlockChain::insertWithoutParent(bytes const& _block, bytesConstRef _receipts, u256 const& _totalDifficulty)
734 {
736 
737  // Check block doesn't already exist first!
738  checkBlockIsNew(block);
739 
740  checkBlockTimestamp(block.info);
741 
742  ImportPerformanceLogger performanceLogger;
743  return insertBlockAndExtras(block, _receipts, _totalDifficulty, performanceLogger);
744 }
745 
746 void BlockChain::checkBlockIsNew(VerifiedBlockRef const& _block) const
747 {
748  if (isKnown(_block.info.hash()))
749  {
750  LOG(m_logger) << _block.info.hash() << " : Not new.";
751  BOOST_THROW_EXCEPTION(AlreadyHaveBlock() << errinfo_block(_block.block.toBytes()));
752  }
753 }
754 
755 void BlockChain::checkBlockTimestamp(BlockHeader const& _header) const
756 {
757  // Check it's not crazy
758  if (_header.timestamp() > utcTime() && !m_params.allowFutureBlocks)
759  {
760  LOG(m_loggerDetail) << _header.hash() << " : Future time " << _header.timestamp()
761  << " (now at " << utcTime() << ")";
762  // Block has a timestamp in the future. This is no good.
763  BOOST_THROW_EXCEPTION(FutureTime());
764  }
765 }
766 
767 ImportRoute BlockChain::insertBlockAndExtras(VerifiedBlockRef const& _block, bytesConstRef _receipts, u256 const& _totalDifficulty, ImportPerformanceLogger& _performanceLogger)
768 {
769  std::unique_ptr<db::WriteBatchFace> blocksWriteBatch = m_blocksDB->createWriteBatch();
770  std::unique_ptr<db::WriteBatchFace> extrasWriteBatch = m_extrasDB->createWriteBatch();
771  h256 newLastBlockHash = currentHash();
772  unsigned newLastBlockNumber = number();
773 
774  try
775  {
776  // ensure parent is cached for later addition.
777  // TODO: this is a bit horrible would be better refactored into an enveloping UpgradableGuard
778  // together with an "ensureCachedWithUpdatableLock(l)" method.
779  // This is safe in practice since the caches don't get flushed nearly often enough to be
780  // done here.
781  details(_block.info.parentHash());
782  DEV_WRITE_GUARDED(x_details)
783  m_details[_block.info.parentHash()].children.push_back(_block.info.hash());
784 
785  _performanceLogger.onStageFinished("collation");
786 
787  blocksWriteBatch->insert(toSlice(_block.info.hash()), db::Slice(_block.block));
788  DEV_READ_GUARDED(x_details)
789  extrasWriteBatch->insert(toSlice(_block.info.parentHash(), ExtraDetails),
790  (db::Slice)dev::ref(m_details[_block.info.parentHash()].rlp()));
791 
792  BlockDetails const details((unsigned)_block.info.number(), _totalDifficulty, _block.info.parentHash(), {});
793  extrasWriteBatch->insert(
795 
796  BlockLogBlooms blb;
797  for (auto i: RLP(_receipts))
798  blb.blooms.push_back(TransactionReceipt(i.data()).bloom());
799  extrasWriteBatch->insert(
800  toSlice(_block.info.hash(), ExtraLogBlooms), (db::Slice)dev::ref(blb.rlp()));
801 
802  extrasWriteBatch->insert(toSlice(_block.info.hash(), ExtraReceipts), (db::Slice)_receipts);
803 
804  _performanceLogger.onStageFinished("writing");
805  }
806  catch (Exception& ex)
807  {
808  addBlockInfo(ex, _block.info, _block.block.toBytes());
809  throw;
810  }
811 
812  h256s route;
813  h256 common;
814  bool isImportedAndBest = false;
815  // This might be the new best block...
816  h256 last = currentHash();
817  if (_totalDifficulty > details(last).totalDifficulty || (m_sealEngine->chainParams().tieBreakingGas &&
818  _totalDifficulty == details(last).totalDifficulty && _block.info.gasUsed() > info(last).gasUsed()))
819  {
820  // don't include bi.hash() in treeRoute, since it's not yet in details DB...
821  // just tack it on afterwards.
822  unsigned commonIndex;
823  tie(route, common, commonIndex) = treeRoute(last, _block.info.parentHash());
824  route.push_back(_block.info.hash());
825 
826  // Most of the time these two will be equal - only when we're doing a chain revert will they not be
827  if (common != last)
828  DEV_READ_GUARDED(x_lastBlockHash)
829  clearCachesDuringChainReversion(number(common) + 1);
830 
831  // Go through ret backwards (i.e. from new head to common) until hash != last.parent and
832  // update m_transactionAddresses, m_blockHashes
833  for (auto i = route.rbegin(); i != route.rend() && *i != common; ++i)
834  {
835  BlockHeader tbi;
836  if (*i == _block.info.hash())
837  tbi = _block.info;
838  else
839  tbi = BlockHeader(block(*i));
840 
841  // Collate logs into blooms.
842  h256s alteredBlooms;
843  {
844  LogBloom blockBloom = tbi.logBloom();
845  blockBloom.shiftBloom<3>(sha3(tbi.author().ref()));
846 
847  // Pre-memoize everything we need before locking x_blocksBlooms
848  for (unsigned level = 0, index = (unsigned)tbi.number(); level < c_bloomIndexLevels; level++, index /= c_bloomIndexSize)
849  blocksBlooms(chunkId(level, index / c_bloomIndexSize));
850 
851  WriteGuard l(x_blocksBlooms);
852  for (unsigned level = 0, index = (unsigned)tbi.number(); level < c_bloomIndexLevels; level++, index /= c_bloomIndexSize)
853  {
854  unsigned i = index / c_bloomIndexSize;
855  unsigned o = index % c_bloomIndexSize;
856  alteredBlooms.push_back(chunkId(level, i));
857  m_blocksBlooms[alteredBlooms.back()].blooms[o] |= blockBloom;
858  }
859  }
860  // Collate transaction hashes and remember who they were.
861  //h256s newTransactionAddresses;
862  {
863  bytes blockBytes;
864  RLP blockRLP(*i == _block.info.hash() ? _block.block : &(blockBytes = block(*i)));
866  ta.blockHash = tbi.hash();
867  for (ta.index = 0; ta.index < blockRLP[1].itemCount(); ++ta.index)
868  extrasWriteBatch->insert(
869  toSlice(sha3(blockRLP[1][ta.index].data()), ExtraTransactionAddress),
870  (db::Slice)dev::ref(ta.rlp()));
871  }
872 
873  // Update database with them.
874  ReadGuard l1(x_blocksBlooms);
875  for (auto const& h: alteredBlooms)
876  extrasWriteBatch->insert(
877  toSlice(h, ExtraBlocksBlooms), (db::Slice)dev::ref(m_blocksBlooms[h].rlp()));
878  extrasWriteBatch->insert(toSlice(h256(tbi.number()), ExtraBlockHash),
879  (db::Slice)dev::ref(BlockHash(tbi.hash()).rlp()));
880  }
881 
882  // FINALLY! change our best hash.
883  {
884  newLastBlockHash = _block.info.hash();
885  newLastBlockNumber = (unsigned)_block.info.number();
886  isImportedAndBest = true;
887  }
888 
889  LOG(m_logger) << " Imported and best " << _totalDifficulty << " (#"
890  << _block.info.number() << "). Has "
891  << (details(_block.info.parentHash()).children.size() - 1)
892  << " siblings. Route: " << route;
893  }
894  else
895  {
896  LOG(m_loggerDetail) << " Imported but not best (oTD: " << details(last).totalDifficulty
897  << " > TD: " << _totalDifficulty << "; " << details(last).number << ".."
898  << _block.info.number() << ")";
899  }
900 
901  try
902  {
903  m_blocksDB->commit(std::move(blocksWriteBatch));
904  }
905  catch (boost::exception& ex)
906  {
907  cwarn << "Error writing to blockchain database: " << boost::diagnostic_information(ex);
908  cwarn << "Fail writing to blockchain database. Bombing out.";
909  exit(-1);
910  }
911 
912  try
913  {
914  m_extrasDB->commit(std::move(extrasWriteBatch));
915  }
916  catch (boost::exception& ex)
917  {
918  cwarn << "Error writing to extras database: " << boost::diagnostic_information(ex);
919  cwarn << "Fail writing to extras database. Bombing out.";
920  exit(-1);
921  }
922 
923 #if ETH_PARANOIA
924  if (isKnown(_block.info.hash()) && !details(_block.info.hash()))
925  {
926  LOG(m_loggerError) << "Known block just inserted has no details.";
927  LOG(m_loggerError) << "Block: " << _block.info;
928  LOG(m_loggerError) << "DATABASE CORRUPTION: CRITICAL FAILURE";
929  exit(-1);
930  }
931 
932  try
933  {
934  State canary(_db, BaseState::Empty);
935  canary.populateFromChain(*this, _block.info.hash());
936  }
937  catch (...)
938  {
939  LOG(m_loggerError) << "Failed to initialise State object form imported block.";
940  LOG(m_loggerError) << "Block: " << _block.info;
941  LOG(m_loggerError) << "DATABASE CORRUPTION: CRITICAL FAILURE";
942  exit(-1);
943  }
944 #endif // ETH_PARANOIA
945 
946  if (m_lastBlockHash != newLastBlockHash)
947  DEV_WRITE_GUARDED(x_lastBlockHash)
948  {
949  m_lastBlockHash = newLastBlockHash;
950  m_lastBlockNumber = newLastBlockNumber;
951  try
952  {
953  m_extrasDB->insert(db::Slice("best"), db::Slice((char const*)&m_lastBlockHash, 32));
954  }
955  catch (boost::exception const& ex)
956  {
957  cwarn << "Error writing to extras database: " << boost::diagnostic_information(ex);
958  cout << "Put" << toHex(bytesConstRef(db::Slice("best"))) << "=>"
959  << toHex(bytesConstRef(db::Slice((char const*)&m_lastBlockHash, 32)));
960  cwarn << "Fail writing to extras database. Bombing out.";
961  exit(-1);
962  }
963  }
964 
965 #if ETH_PARANOIA
966  checkConsistency();
967 #endif // ETH_PARANOIA
968 
969  _performanceLogger.onStageFinished("checkBest");
970 
971  unsigned const gasPerSecond = static_cast<double>(_block.info.gasUsed()) / _performanceLogger.stageDuration("enactment");
972  _performanceLogger.onFinished({
973  {"blockHash", "\""+ _block.info.hash().abridged() + "\""},
974  {"blockNumber", toString(_block.info.number())},
975  {"gasPerSecond", toString(gasPerSecond)},
976  {"transactions", toString(_block.transactions.size())},
977  {"gasUsed", toString(_block.info.gasUsed())}
978  });
979 
980  if (!route.empty())
981  noteCanonChanged();
982 
983  if (isImportedAndBest && m_onBlockImport)
984  m_onBlockImport(_block.info);
985 
986  h256s fresh;
987  h256s dead;
988  bool isOld = true;
989  for (auto const& h: route)
990  if (h == common)
991  isOld = false;
992  else if (isOld)
993  dead.push_back(h);
994  else
995  fresh.push_back(h);
996  return ImportRoute{dead, fresh, _block.transactions};
997 }
998 
999 void BlockChain::clearBlockBlooms(unsigned _begin, unsigned _end)
1000 {
1001  // ... c c c c c c c c c c C o o o o o o
1002  // ... /=15 /=21
1003  // L0...| ' | ' | ' | ' | ' | ' | ' | 'b|x'x|x'x|x'e| /=11
1004  // L1...| ' | ' | ' | ' b | x ' x | x ' e | /=6
1005  // L2...| ' | ' b | x ' x | e /=3
1006  // L3...| ' b | x ' e
1007  // model: c_bloomIndexLevels = 4, c_bloomIndexSize = 2
1008 
1009  // ... /=15 /=21
1010  // L0...| ' ' ' | ' ' ' | ' ' ' | ' ' 'b|x'x'x'x|x'e' ' |
1011  // L1...| ' ' ' b | x ' x ' e ' |
1012  // L2...| b ' x ' e ' |
1013  // model: c_bloomIndexLevels = 2, c_bloomIndexSize = 4
1014 
1015  // algorithm doesn't have the best memoisation coherence, but eh well...
1016 
1017  unsigned beginDirty = _begin;
1018  unsigned endDirty = _end;
1019  for (unsigned level = 0; level < c_bloomIndexLevels; level++, beginDirty /= c_bloomIndexSize, endDirty = (endDirty - 1) / c_bloomIndexSize + 1)
1020  {
1021  // compute earliest & latest index for each level, rebuild from previous levels.
1022  for (unsigned item = beginDirty; item != endDirty; ++item)
1023  {
1024  unsigned bunch = item / c_bloomIndexSize;
1025  unsigned offset = item % c_bloomIndexSize;
1026  auto id = chunkId(level, bunch);
1027  LogBloom acc;
1028  if (!!level)
1029  {
1030  // rebuild the bloom from the previous (lower) level (if there is one).
1031  auto lowerChunkId = chunkId(level - 1, item);
1032  for (auto const& bloom: blocksBlooms(lowerChunkId).blooms)
1033  acc |= bloom;
1034  }
1035  blocksBlooms(id); // make sure it has been memoized.
1036  m_blocksBlooms[id].blooms[offset] = acc;
1037  }
1038  }
1039 }
1040 
1042 {
1043  cout << "Rescuing database..." << endl;
1044 
1045  unsigned u = 1;
1046  while (true)
1047  {
1048  try {
1049  if (isKnown(numberHash(u)))
1050  u *= 2;
1051  else
1052  break;
1053  }
1054  catch (...)
1055  {
1056  break;
1057  }
1058  }
1059  unsigned l = u / 2;
1060  cout << "Finding last likely block number..." << endl;
1061  while (u - l > 1)
1062  {
1063  unsigned m = (u + l) / 2;
1064  cout << " " << m << flush;
1065  if (isKnown(numberHash(m)))
1066  l = m;
1067  else
1068  u = m;
1069  }
1070  cout << " lowest is " << l << endl;
1071  for (; l > 0; --l)
1072  {
1073  h256 h = numberHash(l);
1074  cout << "Checking validity of " << l << " (" << h << ")..." << flush;
1075  try
1076  {
1077  cout << "block..." << flush;
1078  BlockHeader bi(block(h));
1079  cout << "extras..." << flush;
1080  details(h);
1081  cout << "state..." << flush;
1082  if (_db.exists(bi.stateRoot()))
1083  break;
1084  }
1085  catch (...) {}
1086  }
1087  cout << "OK." << endl;
1088  rewind(l);
1089 }
1090 
1091 void BlockChain::rewind(unsigned _newHead)
1092 {
1093  DEV_WRITE_GUARDED(x_lastBlockHash)
1094  {
1095  if (_newHead >= m_lastBlockNumber)
1096  return;
1097  clearCachesDuringChainReversion(_newHead + 1);
1098  m_lastBlockHash = numberHash(_newHead);
1099  m_lastBlockNumber = _newHead;
1100  try
1101  {
1102  m_extrasDB->insert(db::Slice("best"), db::Slice((char const*)&m_lastBlockHash, 32));
1103  }
1104  catch (boost::exception const& ex)
1105  {
1106  cwarn << "Error writing to extras database: " << boost::diagnostic_information(ex);
1107  cout << "Put" << toHex(bytesConstRef(db::Slice("best"))) << "=>"
1108  << toHex(bytesConstRef(db::Slice((char const*)&m_lastBlockHash, 32)));
1109  cwarn << "Fail writing to extras database. Bombing out.";
1110  exit(-1);
1111  }
1112  noteCanonChanged();
1113  }
1114 }
1115 
1116 tuple<h256s, h256, unsigned> BlockChain::treeRoute(h256 const& _from, h256 const& _to, bool _common, bool _pre, bool _post) const
1117 {
1118  if (!_from || !_to)
1119  return make_tuple(h256s(), h256(), 0);
1120 
1121  BlockDetails const fromDetails = details(_from);
1122  BlockDetails const toDetails = details(_to);
1123  // Needed to handle a special case when the parent of inserted block is not present in DB.
1124  if (fromDetails.isNull() || toDetails.isNull())
1125  return make_tuple(h256s(), h256(), 0);
1126 
1127  unsigned fn = fromDetails.number;
1128  unsigned tn = toDetails.number;
1129  h256s ret;
1130  h256 from = _from;
1131  while (fn > tn)
1132  {
1133  if (_pre)
1134  ret.push_back(from);
1135  from = details(from).parent;
1136  fn--;
1137  }
1138 
1139  h256s back;
1140  h256 to = _to;
1141  while (fn < tn)
1142  {
1143  if (_post)
1144  back.push_back(to);
1145  to = details(to).parent;
1146  tn--;
1147  }
1148  for (;; from = details(from).parent, to = details(to).parent)
1149  {
1150  if (_pre && (from != to || _common))
1151  ret.push_back(from);
1152  if (_post && (from != to || (!_pre && _common)))
1153  back.push_back(to);
1154 
1155  if (from == to)
1156  break;
1157  if (!from)
1158  assert(from);
1159  if (!to)
1160  assert(to);
1161  }
1162  ret.reserve(ret.size() + back.size());
1163  unsigned i = ret.size() - (int)(_common && !ret.empty() && !back.empty());
1164  for (auto it = back.rbegin(); it != back.rend(); ++it)
1165  ret.push_back(*it);
1166  return make_tuple(ret, from, i);
1167 }
1168 
1169 void BlockChain::noteUsed(h256 const& _h, unsigned _extra) const
1170 {
1171  auto id = CacheID(_h, _extra);
1172  Guard l(x_cacheUsage);
1173  m_cacheUsage[0].insert(id);
1174  if (m_cacheUsage[1].count(id))
1175  m_cacheUsage[1].erase(id);
1176  else
1177  m_inUse.insert(id);
1178 }
1179 
1180 template <class K, class T> static unsigned getHashSize(unordered_map<K, T> const& _map)
1181 {
1182  unsigned ret = 0;
1183  for (auto const& i: _map)
1184  ret += i.second.size + 64;
1185  return ret;
1186 }
1187 
1188 void BlockChain::updateStats() const
1189 {
1190  m_lastStats.memBlocks = 0;
1191  DEV_READ_GUARDED(x_blocks)
1192  for (auto const& i: m_blocks)
1193  m_lastStats.memBlocks += i.second.size() + 64;
1194  DEV_READ_GUARDED(x_details)
1195  m_lastStats.memDetails = getHashSize(m_details);
1196  size_t logBloomsSize = 0;
1197  size_t blocksBloomsSize = 0;
1198  DEV_READ_GUARDED(x_logBlooms)
1199  logBloomsSize = getHashSize(m_logBlooms);
1200  DEV_READ_GUARDED(x_blocksBlooms)
1201  blocksBloomsSize = getHashSize(m_blocksBlooms);
1202  m_lastStats.memLogBlooms = logBloomsSize + blocksBloomsSize;
1203  DEV_READ_GUARDED(x_receipts)
1204  m_lastStats.memReceipts = getHashSize(m_receipts);
1205  DEV_READ_GUARDED(x_blockHashes)
1206  m_lastStats.memBlockHashes = getHashSize(m_blockHashes);
1207  DEV_READ_GUARDED(x_transactionAddresses)
1208  m_lastStats.memTransactionAddresses = getHashSize(m_transactionAddresses);
1209 }
1210 
1212 {
1213  updateStats();
1214 
1215  if (!_force && chrono::system_clock::now() < m_lastCollection + c_collectionDuration && m_lastStats.memTotal() < c_maxCacheSize)
1216  return;
1217  if (m_lastStats.memTotal() < c_minCacheSize)
1218  return;
1219 
1220  m_lastCollection = chrono::system_clock::now();
1221 
1222  Guard l(x_cacheUsage);
1223  for (CacheID const& id: m_cacheUsage.back())
1224  {
1225  m_inUse.erase(id);
1226  // kill i from cache.
1227  switch (id.second)
1228  {
1229  case (unsigned)-1:
1230  {
1231  WriteGuard l(x_blocks);
1232  m_blocks.erase(id.first);
1233  break;
1234  }
1235  case ExtraDetails:
1236  {
1237  WriteGuard l(x_details);
1238  m_details.erase(id.first);
1239  break;
1240  }
1241  case ExtraBlockHash:
1242  {
1243  // m_cacheUsage should not contain ExtraBlockHash elements currently. See the second noteUsed() in BlockChain.h, which is a no-op.
1244  assert(false);
1245  break;
1246  }
1247  case ExtraReceipts:
1248  {
1249  WriteGuard l(x_receipts);
1250  m_receipts.erase(id.first);
1251  break;
1252  }
1253  case ExtraLogBlooms:
1254  {
1255  WriteGuard l(x_logBlooms);
1256  m_logBlooms.erase(id.first);
1257  break;
1258  }
1260  {
1261  WriteGuard l(x_transactionAddresses);
1262  m_transactionAddresses.erase(id.first);
1263  break;
1264  }
1265  case ExtraBlocksBlooms:
1266  {
1267  WriteGuard l(x_blocksBlooms);
1268  m_blocksBlooms.erase(id.first);
1269  break;
1270  }
1271  }
1272  }
1273  m_cacheUsage.pop_back();
1274  m_cacheUsage.push_front(std::unordered_set<CacheID>{});
1275 }
1276 
1277 void BlockChain::checkConsistency()
1278 {
1279  DEV_WRITE_GUARDED(x_details) { m_details.clear(); }
1280 
1281  m_blocksDB->forEach([this](db::Slice const& _key, db::Slice const& /* _value */) {
1282  if (_key.size() == 32)
1283  {
1284  h256 h((byte const*)_key.data(), h256::ConstructFromPointer);
1285  auto dh = details(h);
1286  auto p = dh.parent;
1287  if (p != h256() && p != m_genesisHash) // TODO: for some reason the genesis details
1288  // with the children get squished. not sure
1289  // why.
1290  {
1291  auto dp = details(p);
1292  if (asserts(contains(dp.children, h)))
1293  cnote << "Apparently the database is corrupt. Not much we can do at this "
1294  "stage...";
1295  if (assertsEqual(dp.number, dh.number - 1))
1296  cnote << "Apparently the database is corrupt. Not much we can do at this "
1297  "stage...";
1298  }
1299  }
1300  return true;
1301  });
1302 }
1303 
1304 void BlockChain::clearCachesDuringChainReversion(unsigned _firstInvalid)
1305 {
1306  unsigned end = m_lastBlockNumber + 1;
1307  DEV_WRITE_GUARDED(x_blockHashes)
1308  for (auto i = _firstInvalid; i < end; ++i)
1309  m_blockHashes.erase(i);
1310  DEV_WRITE_GUARDED(x_transactionAddresses)
1311  m_transactionAddresses.clear(); // TODO: could perhaps delete them individually?
1312 
1313  // If we are reverting previous blocks, we need to clear their blooms (in particular, to
1314  // rebuild any higher level blooms that they contributed to).
1315  clearBlockBlooms(_firstInvalid, end);
1316 }
1317 
1318 static inline unsigned upow(unsigned a, unsigned b) { if (!b) return 1; while (--b > 0) a *= a; return a; }
1319 static inline unsigned ceilDiv(unsigned n, unsigned d) { return (n + d - 1) / d; }
1320 //static inline unsigned floorDivPow(unsigned n, unsigned a, unsigned b) { return n / upow(a, b); }
1321 //static inline unsigned ceilDivPow(unsigned n, unsigned a, unsigned b) { return ceilDiv(n, upow(a, b)); }
1322 
1323 // Level 1
1324 // [xxx. ]
1325 
1326 // Level 0
1327 // [.x............F.]
1328 // [........x.......]
1329 // [T.............x.]
1330 // [............ ]
1331 
1332 // F = 14. T = 32
1333 
1334 vector<unsigned> BlockChain::withBlockBloom(LogBloom const& _b, unsigned _earliest, unsigned _latest) const
1335 {
1336  vector<unsigned> ret;
1337 
1338  // start from the top-level
1339  unsigned u = upow(c_bloomIndexSize, c_bloomIndexLevels);
1340 
1341  // run through each of the top-level blockbloom blocks
1342  for (unsigned index = _earliest / u; index <= ceilDiv(_latest, u); ++index) // 0
1343  ret += withBlockBloom(_b, _earliest, _latest, c_bloomIndexLevels - 1, index);
1344 
1345  return ret;
1346 }
1347 
1348 vector<unsigned> BlockChain::withBlockBloom(LogBloom const& _b, unsigned _earliest, unsigned _latest, unsigned _level, unsigned _index) const
1349 {
1350  // 14, 32, 1, 0
1351  // 14, 32, 0, 0
1352  // 14, 32, 0, 1
1353  // 14, 32, 0, 2
1354 
1355  vector<unsigned> ret;
1356 
1357  unsigned uCourse = upow(c_bloomIndexSize, _level + 1);
1358  // 256
1359  // 16
1360  unsigned uFine = upow(c_bloomIndexSize, _level);
1361  // 16
1362  // 1
1363 
1364  unsigned obegin = _index == _earliest / uCourse ? _earliest / uFine % c_bloomIndexSize : 0;
1365  // 0
1366  // 14
1367  // 0
1368  // 0
1369  unsigned oend = _index == _latest / uCourse ? (_latest / uFine) % c_bloomIndexSize + 1 : c_bloomIndexSize;
1370  // 3
1371  // 16
1372  // 16
1373  // 1
1374 
1375  BlocksBlooms bb = blocksBlooms(_level, _index);
1376  for (unsigned o = obegin; o < oend; ++o)
1377  if (bb.blooms[o].contains(_b))
1378  {
1379  // This level has something like what we want.
1380  if (_level > 0)
1381  ret += withBlockBloom(_b, _earliest, _latest, _level - 1, o + _index * c_bloomIndexSize);
1382  else
1383  ret.push_back(o + _index * c_bloomIndexSize);
1384  }
1385  return ret;
1386 }
1387 
1388 h256Hash BlockChain::allKinFrom(h256 const& _parent, unsigned _generations) const
1389 {
1390  // Get all uncles cited given a parent (i.e. featured as uncles/main in parent, parent + 1, ... parent + 5).
1391  h256 p = _parent;
1392  h256Hash ret = { p };
1393  // p and (details(p).parent: i == 5) is likely to be overkill, but can't hurt to be cautious.
1394  for (unsigned i = 0; i < _generations && p != m_genesisHash; ++i, p = details(p).parent)
1395  {
1396  ret.insert(details(p).parent);
1397  auto b = block(p);
1398  for (auto i: RLP(b)[2])
1399  ret.insert(sha3(i.data()));
1400  }
1401  return ret;
1402 }
1403 
1404 bool BlockChain::isKnown(h256 const& _hash, bool _isCurrent) const
1405 {
1406  if (_hash == m_genesisHash)
1407  return true;
1408 
1409  DEV_READ_GUARDED(x_blocks)
1410  if (!m_blocks.count(_hash) && !m_blocksDB->exists(toSlice(_hash)))
1411  {
1412  return false;
1413  }
1414  DEV_READ_GUARDED(x_details)
1415  if (!m_details.count(_hash) && !m_extrasDB->exists(toSlice(_hash, ExtraDetails)))
1416  {
1417  return false;
1418  }
1419 // return true;
1420  return !_isCurrent || details(_hash).number <= m_lastBlockNumber; // to allow rewind functionality.
1421 }
1422 
1423 bytes BlockChain::block(h256 const& _hash) const
1424 {
1425  if (_hash == m_genesisHash)
1426  return m_params.genesisBlock();
1427 
1428  {
1429  ReadGuard l(x_blocks);
1430  auto it = m_blocks.find(_hash);
1431  if (it != m_blocks.end())
1432  return it->second;
1433  }
1434 
1435  string const d = m_blocksDB->lookup(toSlice(_hash));
1436  if (d.empty())
1437  {
1438  cwarn << "Couldn't find requested block:" << _hash;
1439  return bytes();
1440  }
1441 
1442  noteUsed(_hash);
1443 
1444  WriteGuard l(x_blocks);
1445  m_blocks[_hash].resize(d.size());
1446  memcpy(m_blocks[_hash].data(), d.data(), d.size());
1447 
1448  return m_blocks[_hash];
1449 }
1450 
1451 bytes BlockChain::headerData(h256 const& _hash) const
1452 {
1453  if (_hash == m_genesisHash)
1454  return m_genesisHeaderBytes;
1455 
1456  {
1457  ReadGuard l(x_blocks);
1458  auto it = m_blocks.find(_hash);
1459  if (it != m_blocks.end())
1460  return BlockHeader::extractHeader(&it->second).data().toBytes();
1461  }
1462 
1463  string const d = m_blocksDB->lookup(toSlice(_hash));
1464  if (d.empty())
1465  {
1466  cwarn << "Couldn't find requested block:" << _hash;
1467  return bytes();
1468  }
1469 
1470  noteUsed(_hash);
1471 
1472  WriteGuard l(x_blocks);
1473  m_blocks[_hash].resize(d.size());
1474  memcpy(m_blocks[_hash].data(), d.data(), d.size());
1475 
1476  return BlockHeader::extractHeader(&m_blocks[_hash]).data().toBytes();
1477 }
1478 
1479 Block BlockChain::genesisBlock(OverlayDB const& _db) const
1480 {
1481  h256 r = BlockHeader(m_params.genesisBlock()).stateRoot();
1482  Block ret(*this, _db, BaseState::Empty);
1483  if (!_db.exists(r))
1484  {
1485  ret.noteChain(*this);
1486  dev::eth::commit(m_params.genesisState, ret.mutableState().m_state); // bit horrible. maybe consider a better way of constructing it?
1487  ret.mutableState().db().commit(); // have to use this db() since it's the one that has been altered with the above commit.
1488  if (ret.mutableState().rootHash() != r)
1489  {
1490  cwarn << "Hinted genesis block's state root hash is incorrect!";
1491  cwarn << "Hinted" << r << ", computed" << ret.mutableState().rootHash();
1492  // TODO: maybe try to fix it by altering the m_params's genesis block?
1493  exit(-1);
1494  }
1495  }
1496  ret.m_previousBlock = BlockHeader(m_params.genesisBlock());
1497  ret.resetCurrent();
1498  return ret;
1499 }
1500 
1501 VerifiedBlockRef BlockChain::verifyBlock(bytesConstRef _block, std::function<void(Exception&)> const& _onBad, ImportRequirements::value _ir) const
1502 {
1503  VerifiedBlockRef res;
1504  BlockHeader h;
1505  try
1506  {
1507  h = BlockHeader(_block);
1508  if (!!(_ir & ImportRequirements::PostGenesis) && (!h.parentHash() || h.number() == 0))
1509  BOOST_THROW_EXCEPTION(InvalidParentHash() << errinfo_required_h256(h.parentHash()) << errinfo_currentNumber(h.number()));
1510 
1511  BlockHeader parent;
1512  if (!!(_ir & ImportRequirements::Parent))
1513  {
1514  bytes parentHeader(headerData(h.parentHash()));
1515  if (parentHeader.empty())
1516  BOOST_THROW_EXCEPTION(InvalidParentHash() << errinfo_required_h256(h.parentHash()) << errinfo_currentNumber(h.number()));
1517  parent = BlockHeader(parentHeader, HeaderData, h.parentHash());
1518  }
1519  sealEngine()->verify((_ir & ImportRequirements::ValidSeal) ? Strictness::CheckEverything : Strictness::QuickNonce, h, parent, _block);
1520  res.info = h;
1521  }
1522  catch (Exception& ex)
1523  {
1524  ex << errinfo_phase(1);
1525  addBlockInfo(ex, h, _block.toBytes());
1526  if (_onBad)
1527  _onBad(ex);
1528  throw;
1529  }
1530 
1531  RLP r(_block);
1532  unsigned i = 0;
1533  if (_ir & (ImportRequirements::UncleBasic | ImportRequirements::UncleParent | ImportRequirements::UncleSeals))
1534  for (auto const& uncle: r[2])
1535  {
1536  BlockHeader uh(uncle.data(), HeaderData);
1537  try
1538  {
1539  BlockHeader parent;
1540  if (!!(_ir & ImportRequirements::UncleParent))
1541  {
1542  bytes parentHeader(headerData(uh.parentHash()));
1543  if (parentHeader.empty())
1544  BOOST_THROW_EXCEPTION(InvalidUncleParentHash() << errinfo_required_h256(uh.parentHash()) << errinfo_currentNumber(h.number()) << errinfo_uncleNumber(uh.number()));
1545  parent = BlockHeader(parentHeader, HeaderData, uh.parentHash());
1546  }
1547  sealEngine()->verify((_ir & ImportRequirements::UncleSeals) ? Strictness::CheckEverything : Strictness::IgnoreSeal, uh, parent);
1548  }
1549  catch (Exception& ex)
1550  {
1551  ex << errinfo_phase(1);
1552  ex << errinfo_uncleIndex(i);
1553  addBlockInfo(ex, uh, _block.toBytes());
1554  if (_onBad)
1555  _onBad(ex);
1556  throw;
1557  }
1558  ++i;
1559  }
1560  i = 0;
1561  if (_ir & (ImportRequirements::TransactionBasic | ImportRequirements::TransactionSignatures))
1562  for (RLP const& tr: r[1])
1563  {
1564  bytesConstRef d = tr.data();
1565  try
1566  {
1567  Transaction t(d, (_ir & ImportRequirements::TransactionSignatures) ? CheckTransaction::Everything : CheckTransaction::None);
1568  m_sealEngine->verifyTransaction(_ir, t, h, 0); // the gasUsed vs blockGasLimit is checked later in enact function
1569  res.transactions.push_back(t);
1570  }
1571  catch (Exception& ex)
1572  {
1573  ex << errinfo_phase(1);
1574  ex << errinfo_transactionIndex(i);
1575  ex << errinfo_transaction(d.toBytes());
1576  addBlockInfo(ex, h, _block.toBytes());
1577  if (_onBad)
1578  _onBad(ex);
1579  throw;
1580  }
1581  ++i;
1582  }
1583  res.block = bytesConstRef(_block);
1584  return res;
1585 }
1586 
1587 void BlockChain::setChainStartBlockNumber(unsigned _number)
1588 {
1589  h256 const hash = numberHash(_number);
1590  if (!hash)
1591  BOOST_THROW_EXCEPTION(UnknownBlockNumber());
1592 
1593  try
1594  {
1595  m_extrasDB->insert(
1596  c_sliceChainStart, db::Slice(reinterpret_cast<char const*>(hash.data()), h256::size));
1597  }
1598  catch (boost::exception const& ex)
1599  {
1600  BOOST_THROW_EXCEPTION(FailedToWriteChainStart()
1601  << errinfo_hash256(hash)
1602  << boost::errinfo_nested_exception(boost::copy_exception(ex)));
1603  }
1604 }
1605 
1606 unsigned BlockChain::chainStartBlockNumber() const
1607 {
1608  auto const value = m_extrasDB->lookup(c_sliceChainStart);
1609  return value.empty() ? 0 : number(h256(value, h256::FromBinary));
1610 }
dev::eth::errinfo_block
boost::error_info< struct tag_block, bytes > errinfo_block
Definition: State.h:48
dev::eth::BlockQueue::drain
void drain(std::vector< VerifiedBlock > &o_out, unsigned _max)
Definition: BlockQueue.cpp:434
dev::eth::ImportPerformanceLogger::onFinished
void onFinished(std::unordered_map< std::string, std::string > const &_additionalValues)
Definition: ImportPerformanceLogger.h:50
dev::eth::BlockChain::currentHash
h256 currentHash() const
Get a given block (RLP format). Thread-safe.
Definition: BlockChain.h:228
dev::eth::VerifiedBlock
Verified block info, combines block data and verified info/transactions.
Definition: VerifiedBlock.h:45
dev::eth::ChainOperationParams::allowFutureBlocks
bool allowFutureBlocks
Definition: ChainOperationParams.h:105
dev::eth::BlockQueue
A queue of blocks. Sits between network or other I/O and the BlockChain. Sorts them ready for blockch...
Definition: BlockQueue.h:224
dev::eth::ImportResult::AlreadyKnown
@ AlreadyKnown
dev::eth::Block::mutableState
State & mutableState()
Definition: Block.h:175
dev::eth::c_databaseVersion
const unsigned c_databaseVersion
Current database version.
Definition: Common.cpp:51
dev::FixedHash::shiftBloom
FixedHash & shiftBloom(FixedHash< M > const &_h)
Definition: FixedHash.h:175
dev::FixedHash< 32 >::FromBinary
@ FromBinary
Definition: FixedHash.h:59
dev::eth::TransactionAddress::rlp
bytes rlp() const
Definition: BlockDetails.h:104
dev::eth::BlockChain::Statistics::memLogBlooms
unsigned memLogBlooms
Definition: BlockChain.h:278
dev::ref
vector_ref< _T const > ref(_T const &_t)
Definition: vector_ref.h:109
dev::eth::State::rootHash
h256 rootHash() const
The hash of the root of our state tree.
Definition: State.h:310
dev::eth::BlockChain::insert
void insert(bytes const &_block, bytesConstRef _receipts, bool _mustBeNew=true)
Definition: BlockChain.cpp:540
dev::eth::BlockHash
Definition: BlockDetails.h:90
dev::eth::VerifiedBlocks
std::vector< VerifiedBlock > VerifiedBlocks
Definition: VerifiedBlock.h:76
dev::eth::BlockChain::Statistics::memDetails
unsigned memDetails
Definition: BlockChain.h:277
dev::contents
bytes contents(boost::filesystem::path const &_file)
Definition: CommonIO.cpp:107
dev::eth::Transaction
Encodes a transaction, ready to be exported to or freshly imported from RLP.
Definition: Transaction.h:86
dev::db::databasePath
fs::path databasePath()
Definition: DBFactory.cpp:97
dev::eth::BlockHeader::hash
h256 hash(IncludeSeal _i=WithSeal) const
Definition: BlockHeader.cpp:119
dev::eth::ImportRequirements::Everything
@ Everything
Definition: Common.h:127
dev::db::isDiskDatabase
bool isDiskDatabase()
Definition: DBFactory.cpp:80
dev::eth::BlockChain::rescue
void rescue(OverlayDB const &_db)
Rescue the database.
Definition: BlockChain.cpp:1041
dev::toBigEndian
void toBigEndian(T _val, Out &o_out)
Definition: CommonData.h:124
dev::eth::TransactionAddress
Definition: BlockDetails.h:101
dev::eth::HeaderData
@ HeaderData
Definition: BlockHeader.h:69
dev::eth::BlockChain::rebuild
void rebuild(boost::filesystem::path const &_path, ProgressCallback const &_progress=std::function< void(unsigned, unsigned)>())
Definition: BlockChain.cpp:341
dev::WithExisting::Verify
@ Verify
dev::vector_ref
Definition: vector_ref.h:22
dev::eth::BlockHeader
Encapsulation of a block header. Class to contain all of a block header's data. It is able to parse a...
Definition: BlockHeader.h:97
dev::eth::BlockChain::treeRoute
std::tuple< h256s, h256, unsigned > treeRoute(h256 const &_from, h256 const &_to, bool _common=true, bool _pre=true, bool _post=true) const
Definition: BlockChain.cpp:1116
dev::eth::BlockDetails::rlp
bytes rlp() const
Definition: BlockDetails.cpp:38
dev::UpgradableGuard
boost::upgrade_lock< boost::shared_mutex > UpgradableGuard
Definition: Guards.h:45
dev::eth::BlockChain::attemptImport
std::pair< ImportResult, ImportRoute > attemptImport(bytes const &_block, OverlayDB const &_stateDB, bool _mutBeNew=true) noexcept
Definition: BlockChain.cpp:507
dev::eth::Transactions
std::vector< Transaction > Transactions
Nice name for vector of Transaction.
Definition: Transaction.h:122
dev::FixedHash::data
byte * data()
Definition: FixedHash.h:138
dev::eth::BlockChain::Statistics::memTotal
unsigned memTotal() const
Definition: BlockChain.h:282
dev::eth::BlockHeader::extraData
bytes const & extraData() const
Definition: BlockHeader.h:168
dev::eth::State::openDB
static OverlayDB openDB(boost::filesystem::path const &_path, h256 const &_genesisHash, WithExisting _we=WithExisting::Trust)
Open a DB - useful for passing into the constructor & keeping for other states that are necessary.
Definition: State.cpp:60
dev::eth::BlockDetails::children
h256s children
Definition: BlockDetails.h:54
dev::sha3
bool sha3(bytesConstRef _input, bytesRef o_output) noexcept
Definition: SHA3.cpp:28
dev::eth::Block::enactOn
u256 enactOn(VerifiedBlockRef const &_block, BlockChain const &_bc)
Definition: Block.cpp:414
dev::eth::BaseState::Empty
@ Empty
dev::eth::BlockChain::reopen
void reopen(WithExisting _we=WithExisting::Trust, ProgressCallback const &_pc=ProgressCallback())
Reopen everything.
Definition: BlockChain.h:113
dev::eth::ChainParams
Definition: ChainParams.h:38
ImportPerformanceLogger.h
dev::eth::BlockChain::genesisHash
h256 genesisHash() const
Get the hash of the genesis block. Thread-safe.
Definition: BlockChain.h:231
dev::Guard
std::lock_guard< std::mutex > Guard
Definition: Guards.h:41
FixedHash.h
dev::eth::ExtraBlocksBlooms
@ ExtraBlocksBlooms
Definition: BlockChain.h:89
dev::FixedHash::ref
bytesRef ref()
Definition: FixedHash.h:132
GenesisInfo.h
dev::eth::BlockChain::blockBloom
LogBloom blockBloom(unsigned _number) const
Definition: BlockChain.h:204
dev::errinfo_hash256
boost::error_info< struct tag_hash, h256 > errinfo_hash256
Definition: Exceptions.h:89
dev::Timer
Definition: Common.h:256
dev::eth::BlockHeader::stateRoot
h256 const & stateRoot() const
Definition: BlockHeader.h:162
dev::eth::BlockHeader::logBloom
LogBloom const & logBloom() const
Definition: BlockHeader.h:169
dev::eth::BlockChain::isKnown
bool isKnown(h256 const &_hash, bool _isCurrent=true) const
Returns true if the given block is known (though not necessarily a part of the canon chain).
Definition: BlockChain.cpp:1404
dev::eth::ExtraReceipts
@ ExtraReceipts
Definition: BlockChain.h:88
dev::h256
FixedHash< 32 > h256
Definition: FixedHash.h:356
dev::eth::BlockChain::Statistics::memBlockHashes
unsigned memBlockHashes
Definition: BlockChain.h:281
dev::eth::ImportRequirements::value
unsigned value
Definition: Common.h:112
dev::errinfo_extraData
boost::error_info< struct tag_extraData, bytes > errinfo_extraData
Definition: Exceptions.h:93
dev::orderedTrieRoot
h256 orderedTrieRoot(std::vector< bytes > const &_data)
Definition: TrieHash.cpp:112
Exceptions.h
dev::eth::QuickNonce
@ QuickNonce
Definition: BlockHeader.h:49
dev::eth::VerifiedBlockRef::block
bytesConstRef block
Block data reference.
Definition: VerifiedBlock.h:38
dev::eth::commit
AddressHash commit(AccountMap const &_cache, SecureTrieDB< Address, DB > &_state)
Definition: State.cpp:759
dev::eth::BlockChain::sync
std::tuple< ImportRoute, bool, unsigned > sync(BlockQueue &_bq, OverlayDB const &_stateDB, unsigned _max)
Definition: BlockChain.cpp:443
dev::eth::ImportRequirements::InOrderChecks
@ InOrderChecks
Do all checks that cannot be done independently of prior blocks having been imported.
Definition: Common.h:126
dev::eth
Definition: BasicAuthority.h:32
dev::eth::BlockChain::number
unsigned number() const
Definition: BlockChain.h:225
dev::eth::bloom
LogBloom bloom(LogEntries const &_logs)
Definition: LogEntry.h:96
dev::eth::ExtraBlockHash
@ ExtraBlockHash
Definition: BlockChain.h:85
dev::OverlayDB::exists
bool exists(h256 const &_h) const
Definition: OverlayDB.cpp:134
dev::eth::BlockHeader::clear
void clear()
Definition: BlockHeader.cpp:100
dev::toString
std::string toString(std::chrono::time_point< T > const &_e, std::string const &_format="%F %T")
Definition: CommonIO.h:86
BlockHeader.h
dev::rlp
bytes rlp(_T _t)
Export a single item in RLP format, returning a byte array.
Definition: RLP.h:453
dev::utcTime
int64_t utcTime()
Get the current time in seconds since the epoch in UTC.
Definition: Common.cpp:53
dev::eth::BlockChain::~BlockChain
~BlockChain()
Definition: BlockChain.cpp:180
dev::eth::BlockDetails
Definition: BlockDetails.h:42
dev::eth::BlockDetails::isNull
bool isNull() const
Definition: BlockDetails.h:48
dev::eth::ImportResult::Malformed
@ Malformed
dev::FixedHash< 32 >
dev::eth::TransactionAddress::blockHash
h256 blockHash
Definition: BlockDetails.h:108
dev::Timer::elapsed
double elapsed() const
Definition: Common.h:261
dev::eth::ChainParams::createSealEngine
SealEngineFace * createSealEngine()
Definition: ChainParams.cpp:165
dev::WithExisting::Kill
@ Kill
dev::eth::ProgressCallback
std::function< void(unsigned, unsigned)> ProgressCallback
Definition: BlockChain.h:92
dev::eth::Block::noteChain
void noteChain(BlockChain const &_bc)
Definition: Block.cpp:146
DEV_TIMED_ABOVE
#define DEV_TIMED_ABOVE(S, MS)
Definition: Common.h:276
dev::OverlayDB::commit
void commit()
Definition: OverlayDB.cpp:48
dev::eth::ExtraTransactionAddress
@ ExtraTransactionAddress
Definition: BlockChain.h:86
dev::WithExisting
WithExisting
Definition: Common.h:292
dev::Exception
Base class for all exceptions.
Definition: Exceptions.h:39
LOG
#define LOG
Definition: Log.h:63
dev::WriteGuard
boost::unique_lock< boost::shared_mutex > WriteGuard
Definition: Guards.h:47
dev::eth::BlockDetails::number
unsigned number
Definition: BlockDetails.h:51
dev::eth::BlockChain::block
bytes block() const
Definition: BlockChain.h:150
dev::eth::BlockChain::import
ImportRoute import(bytes const &_block, OverlayDB const &_stateDB, bool _mustBeNew=true)
Definition: BlockChain.cpp:533
dev::eth::errinfo_phase
boost::error_info< struct tag_phase, unsigned > errinfo_phase
Definition: State.h:56
dev::h256Hash
std::unordered_set< h256 > h256Hash
Definition: FixedHash.h:365
dev::h256s
std::vector< h256 > h256s
Definition: FixedHash.h:361
cnote
#define cnote
Common.h
dev::eth::BlockDetails::totalDifficulty
u256 totalDifficulty
Definition: BlockDetails.h:52
Block.h
dev::eth::BlockHeader::parentHash
h256 const & parentHash() const
Definition: BlockHeader.h:157
dev::eth::ImportRequirements::OutOfOrderChecks
@ OutOfOrderChecks
Do all checks that can be done independently of prior blocks having been imported.
Definition: Common.h:125
dev::eth::BlockHeader::extractHeader
static RLP extractHeader(bytesConstRef _block)
Definition: BlockHeader.cpp:156
dev::eth::BlockChain::details
BlockDetails details() const
Definition: BlockChain.h:158
dev::errinfo_required_h256
boost::error_info< struct tag_required_h256, h256 > errinfo_required_h256
Definition: Exceptions.h:90
dev::eth::ChainParams::genesisBlock
bytes genesisBlock() const
Genesis block info.
Definition: ChainParams.cpp:225
dev::vector_ref::cropped
vector_ref< _T > cropped(size_t _begin, size_t _count) const
Definition: vector_ref.h:60
dev::db::DatabaseStatus::IOError
@ IOError
dev::eth::BlockChain::numberHash
h256 numberHash(unsigned _i) const
Get the hash for a given block's number.
Definition: BlockChain.h:184
dev::eth::BlockChain::Statistics::memReceipts
unsigned memReceipts
Definition: BlockChain.h:279
dev::eth::errinfo_transactionIndex
boost::error_info< struct tag_transactionIndex, unsigned > errinfo_transactionIndex
Definition: State.h:51
dev::eth::BlockLogBlooms
Definition: BlockDetails.h:60
dev::eth::Block::cleanup
void cleanup()
Returns back to a pristine state after having done a playback.
Definition: Block.cpp:879
dev::eth::BlocksBlooms
Definition: BlockDetails.h:70
DEV_WRITE_GUARDED
#define DEV_WRITE_GUARDED(MUTEX)
Definition: Guards.h:136
dev::bytes
std::vector< byte > bytes
Definition: Common.h:72
dev::eth::BlockChain::verifyBlock
VerifiedBlockRef verifyBlock(bytesConstRef _block, std::function< void(Exception &)> const &_onBad, ImportRequirements::value _ir=ImportRequirements::OutOfOrderChecks) const
Verify block and prepare it for enactment.
Definition: BlockChain.cpp:1501
dev::eth::errinfo_uncleNumber
boost::error_info< struct tag_uncleNumber, u256 > errinfo_uncleNumber
Definition: State.h:46
dev::vector_ref::toString
std::string toString() const
Definition: vector_ref.h:44
dev::FixedHash::abridged
std::string abridged() const
Definition: FixedHash.h:123
dev::eth::Block::pending
Transactions const & pending() const
Get the list of pending transactions.
Definition: Block.h:183
dev::vector_ref::data
_T * data() const
Definition: vector_ref.h:49
dev::eth::BlockLogBlooms::rlp
bytes rlp() const
Definition: BlockDetails.h:63
dev::bytesConstRef
vector_ref< byte const > bytesConstRef
Definition: Common.h:74
dev::ReadGuard
boost::shared_lock< boost::shared_mutex > ReadGuard
Definition: Guards.h:44
dev::eth::BlockChain
Implements the blockchain database. All data this gives is disk-backed. @threadsafe.
Definition: BlockChain.h:105
dev::eth::CheckEverything
@ CheckEverything
Definition: BlockHeader.h:48
dev::eth::ImportRoute::liveBlocks
h256s liveBlocks
Definition: Common.h:92
dev::eth::BlockHeader::number
int64_t number() const
Definition: BlockHeader.h:166
dev::eth::ImportPerformanceLogger::stageDuration
double stageDuration(std::string const &_name) const
Definition: ImportPerformanceLogger.h:44
TrieHash.h
dev::eth::BlockReceipts::receipts
TransactionReceipts receipts
Definition: BlockDetails.h:85
dev::vector_ref::size
size_t size() const
Definition: vector_ref.h:53
dev::OverlayDB
Definition: OverlayDB.h:34
dev::eth::BlockChain::info
BlockHeader info() const
Definition: BlockChain.h:146
BlockChain.h
DBFactory.h
dev::eth::errinfo_uncleIndex
boost::error_info< struct tag_uncleIndex, unsigned > errinfo_uncleIndex
Definition: State.h:44
dev::RLP::data
bytesConstRef data() const
The bare data of the RLP.
Definition: RLP.h:80
FileSystem.h
dev::bytesRef
vector_ref< byte > bytesRef
Definition: Common.h:73
dev::eth::IgnoreSeal
@ IgnoreSeal
Definition: BlockHeader.h:50
dev::eth::TransactionAddress::index
unsigned index
Definition: BlockDetails.h:109
dev::eth::BlockReceipts::rlp
bytes rlp() const
Definition: BlockDetails.h:83
dev::Mutex
std::mutex Mutex
Definition: Guards.h:37
dev::eth::ImportRoute::deadBlocks
h256s deadBlocks
Definition: Common.h:91
dev::eth::BlockChain::genesis
BlockHeader const & genesis() const
Definition: BlockChain.cpp:185
dev::eth::ImportPerformanceLogger
Definition: ImportPerformanceLogger.h:36
dev::Timer::restart
void restart()
Definition: Common.h:262
DEV_READ_GUARDED
#define DEV_READ_GUARDED(MUTEX)
Definition: Guards.h:134
dev::eth::State::db
OverlayDB const & db() const
Definition: State.h:195
dev::eth::BlockDetails::parent
h256 parent
Definition: BlockDetails.h:53
dev::eth::c_minorProtocolVersion
const unsigned c_minorProtocolVersion
Current minor protocol version.
Definition: Common.cpp:46
dev::UpgradeGuard
boost::upgrade_to_unique_lock< boost::shared_mutex > UpgradeGuard
Definition: Guards.h:46
dev::eth::Block::resetCurrent
void resetCurrent(int64_t _timestamp=utcTime())
Definition: Block.cpp:118
dev::db::DBFactory::create
static std::unique_ptr< DatabaseFace > create()
Definition: DBFactory.cpp:135
dev::toBigEndianString
std::string toBigEndianString(u256 _val)
Convenience functions for toBigEndian.
Definition: CommonData.h:147
dev::eth::Block::db
OverlayDB const & db() const
Open a DB - useful for passing into the constructor & keeping for other states that are necessary.
Definition: Block.h:161
Assertions.h
dev::FixedHash< 32 >::size
@ size
Definition: FixedHash.h:53
dev::contains
bool contains(T const &_t, V const &_v)
Definition: CommonData.h:324
dev::eth::ImportRequirements
Definition: Common.h:111
dev::eth::Block::receipt
TransactionReceipt const & receipt(unsigned _i) const
Get the transaction receipt for the transaction of the given index.
Definition: Block.h:189
dev::vector_ref::toBytes
std::vector< unsigned char > toBytes() const
Definition: vector_ref.h:43
std
Definition: FixedHash.h:393
dev::eth::Success
@ Success
Definition: Common.h:223
dev::eth::BlockChain::Statistics::memBlocks
unsigned memBlocks
Definition: BlockChain.h:276
dev::eth::State
Definition: State.h:160
dev::u256
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void > > u256
Definition: Common.h:121
dev::eth::errinfo_transaction
boost::error_info< struct tag_transaction, bytes > errinfo_transaction
Definition: State.h:55
dev::eth::VerifiedBlockRef::transactions
std::vector< Transaction > transactions
Verified list of block transactions.
Definition: VerifiedBlock.h:40
dev::eth::operator<<
std::ostream & operator<<(std::ostream &_out, BlockHeader const &_bi)
Definition: BlockHeader.h:217
dev::eth::errinfo_currentNumber
boost::error_info< struct tag_currentNumber, u256 > errinfo_currentNumber
Definition: State.h:45
dev::eth::BlockChain::garbageCollect
void garbageCollect(bool _force=false)
Deallocate unused data.
Definition: BlockChain.cpp:1211
dev::eth::VerifiedBlockRef
Verified block info, does not hold block data, but a reference instead.
Definition: VerifiedBlock.h:37
dev::eth::BlockChain::insertWithoutParent
ImportRoute insertWithoutParent(bytes const &_block, bytesConstRef _receipts, u256 const &_totalDifficulty)
Insert that doesn't require parent to be imported, useful when we don't have the full blockchain (lik...
Definition: BlockChain.cpp:733
dev::eth::TransactionReceipt
Definition: TransactionReceipt.h:40
dev::eth::ImportRoute
Definition: Common.h:90
dev::eth::BlockHeader::author
Address const & author() const
Definition: BlockHeader.h:161
dev::eth::BlockReceipts
Definition: BlockDetails.h:80
dev
Definition: Address.cpp:21
dev::eth::ImportPerformanceLogger::onStageFinished
void onStageFinished(std::string const &_name)
Definition: ImportPerformanceLogger.h:38
dev::vector_ref::reset
void reset()
Definition: vector_ref.h:102
dev::eth::Block::info
BlockHeader const & info() const
Get the header information on the present block.
Definition: Block.h:273
dev::eth::ImportResult::FutureTimeKnown
@ FutureTimeKnown
dev::eth::BlockChain::blocksBlooms
BlocksBlooms blocksBlooms(unsigned _level, unsigned _index) const
Definition: BlockChain.h:202
dev::eth::BlockChain::dumpDatabase
std::string dumpDatabase() const
Gives a dump of the blockchain database. For debug/test use only.
Definition: BlockChain.cpp:424
dev::eth::BlockHeader::receiptsRoot
h256 const & receiptsRoot() const
Definition: BlockHeader.h:164
cwarn
#define cwarn
dev::eth::ImportRoute::goodTranactions
std::vector< Transaction > goodTranactions
Definition: Common.h:93
dev::writeFile
void writeFile(boost::filesystem::path const &_file, bytesConstRef _data, bool _writeDeleteRename)
Definition: CommonIO.cpp:125
DEV_IGNORE_EXCEPTIONS
#define DEV_IGNORE_EXCEPTIONS(X)
Definition: Common.h:59
dev::eth::BlockChain::rewind
void rewind(unsigned _newHead)
Alter the head of the chain to some prior block along it.
Definition: BlockChain.cpp:1091
dev::eth::errinfo_now
boost::error_info< struct tag_now, unsigned > errinfo_now
Definition: State.h:49
dev::eth::toSlice
db::Slice toSlice(h256 const &_h, unsigned _sub=0)
Definition: BlockChain.cpp:78
dev::toHex
std::string toHex(Iterator _it, Iterator _end, std::string const &_prefix)
Definition: CommonData.h:46
dev::eth::ImportResult::UnknownParent
@ UnknownParent
dev::eth::LastBlockHashesFace
Interface for getting a list of recent block hashes @threadsafe.
Definition: LastBlockHashesFace.h:37
dev::eth::TransactionReceipt::bloom
LogBloom const & bloom() const
Definition: TransactionReceipt.h:55
dev::RLP
Definition: RLP.h:48
dev::eth::BlockQueue::doneDrain
bool doneDrain(h256s const &_knownBad=h256s())
Definition: BlockQueue.cpp:332
dev::eth::ExtraDetails
@ ExtraDetails
Definition: BlockChain.h:84
dev::eth::BlockHeader::difficulty
u256 const & difficulty() const
Definition: BlockHeader.h:170
dev::eth::BlockHash::rlp
bytes rlp() const
Definition: BlockDetails.h:94
RLP.h
dev::eth::Block
Active model of a block within the block chain. Keeps track of all transactions, receipts and state f...
Definition: Block.h:69
dev::eth::BlockChain::Statistics::memTransactionAddresses
unsigned memTransactionAddresses
Definition: BlockChain.h:280
dev::eth::BlockHeader::gasUsed
u256 const & gasUsed() const
Definition: BlockHeader.h:165
State.h
dev::eth::BlockChain::genesisBlock
Block genesisBlock(OverlayDB const &_db) const
Get a pre-made genesis State object.
Definition: BlockChain.cpp:1479
dev::eth::BlockHeader::timestamp
int64_t timestamp() const
Definition: BlockHeader.h:160
dev::eth::BlockChain::receipts
BlockReceipts receipts() const
Definition: BlockChain.h:167
dev::eth::BlockLogBlooms::blooms
LogBlooms blooms
Definition: BlockDetails.h:65
dev::eth::VerifiedBlockRef::info
BlockHeader info
Prepopulated block info.
Definition: VerifiedBlock.h:39
ctrace
#define ctrace
dev::eth::ExtraLogBlooms
@ ExtraLogBlooms
Definition: BlockChain.h:87