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