24 #if ETH_PROFILING_GPERF 25 #include <gperftools/profiler.h> 28 #include <boost/timer.hpp> 29 #include <boost/filesystem.hpp> 46 namespace fs = boost::filesystem;
49 #define ETH_TIMED_IMPORTS 1 67 for (it->SeekToFirst(); it->Valid(); it->Next())
68 if (it->key().ToString() !=
"best")
72 _out <<
toHex(it->key().ToString()) <<
": " << d.
number() <<
" @ " << d.
parentHash() << (cmp == it->key().ToString() ?
" BEST" :
"") << std::endl;
84 #if ALL_COMPILERS_ARE_CPP11_COMPLIANT 86 h[32] = (uint8_t)_sub;
87 return (ldb::Slice)h.
ref();
89 static boost::thread_specific_ptr<FixedHash<33>> t_h;
93 (*t_h)[32] = (uint8_t)_sub;
94 return (ldb::Slice)t_h->
ref();
95 #endif //ALL_COMPILERS_ARE_CPP11_COMPLIANT 100 #if ALL_COMPILERS_ARE_CPP11_COMPLIANT 103 h[32] = (uint8_t)_sub;
104 return (ldb::Slice)h.ref();
106 static boost::thread_specific_ptr<FixedHash<33>> t_h;
111 (*t_h)[32] = (uint8_t)_sub;
112 return (ldb::Slice)t_h->ref();
127 static const unsigned c_collectionQueueSize = 2;
128 static const unsigned c_maxCacheSize = 1024 * 1024 * 1;
129 static const unsigned c_minCacheSize = 1;
136 static const unsigned c_collectionQueueSize = 20;
139 static const unsigned c_maxCacheSize = 1024 * 1024 * 64;
142 static const unsigned c_minCacheSize = 1024 * 1024 * 32;
150 open(_dbPath, _we, _pc);
191 fs::create_directories(extrasPath);
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);
209 cnote <<
"Killing blockchain & extras database (WithExisting::Kill).";
210 boost::filesystem::remove_all(chainPath +
"/blocks");
211 boost::filesystem::remove_all(extrasPath +
"/extras");
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);
221 if (boost::filesystem::space(chainPath +
"/blocks").available < 1024)
223 cwarn <<
"Not enough available space found on hard drive. Please free some up and then re-run. Bailing.";
224 BOOST_THROW_EXCEPTION(NotEnoughAvailableSpace());
230 (chainPath +
"/blocks") <<
232 (extrasPath +
"/extras") <<
233 "already open. You appear to have another instance of ethereum running. Bailing.";
234 BOOST_THROW_EXCEPTION(DatabaseAlreadyOpen());
279 ctrace <<
"Closing blockchain DB";
303 #if ETH_PROFILING_GPERF 304 ProfilerStart(
"BlockChain_rebuild.log");
318 boost::filesystem::rename(extrasPath +
"/extras", extrasPath +
"/extras.old");
321 o.create_if_missing =
true;
322 ldb::DB::Open(o, extrasPath +
"/extras.old", &oldExtrasDB);
323 ldb::DB::Open(o, extrasPath +
"/extras", &
m_extrasDB);
345 for (
unsigned d = 1;
d <= originalNumber; ++
d)
349 cerr <<
"\n1000 blocks in " << t.
elapsed() <<
"s = " << (1000.0 / t.
elapsed()) <<
"b/s" << endl;
360 cwarn <<
"DISJOINT CHAIN DETECTED; " << bi.
hash() <<
"#" <<
d <<
" -> parent is" << bi.
parentHash() <<
"; expected" << lastHash <<
"#" << (
d - 1);
363 lastHash = bi.
hash();
364 import(
b, s.
db(), 0);
373 _progress(
d, originalNumber);
376 #if ETH_PROFILING_GPERF 381 boost::filesystem::remove_all(path +
"/extras.old");
390 for (i->SeekToFirst(); i->Valid(); i->Next())
402 for (
unsigned i = 0; i < 255; ++i)
413 _bq.
drain(blocks, _max);
431 goodTransactions.reserve(goodTransactions.size() + r.
goodTranactions.size());
435 catch (dev::eth::AlreadyHaveBlock
const&)
437 cwarn <<
"ODD: Import queue contains already imported block";
440 catch (dev::eth::UnknownParent)
442 cwarn <<
"ODD: Import queue contains block with unknown parent.";
445 badBlocks.push_back(
block.verified.info.hash());
447 catch (dev::eth::FutureTime)
449 cwarn <<
"ODD: Import queue contains a block with future time.";
450 this_thread::sleep_for(chrono::seconds(1));
453 catch (dev::eth::TransientError)
455 this_thread::sleep_for(chrono::milliseconds(100));
465 badBlocks.push_back(
block.verified.info.hash());
482 catch (AlreadyHaveBlock&)
519 return import(
block, _db, _mustBeNew);
543 insert(block, _receipts, _mustBeNew);
552 BOOST_THROW_EXCEPTION(AlreadyHaveBlock());
565 for (
auto i:
RLP(_receipts))
566 receipts.push_back(i.data());
572 BOOST_THROW_EXCEPTION(InvalidReceiptsStateRoot());
578 auto pdata = pd.
rlp();
594 BOOST_THROW_EXCEPTION(FutureTime());
601 ldb::WriteBatch blocksBatch;
602 ldb::WriteBatch extrasBatch;
605 for (
auto i:
RLP(_receipts))
632 cwarn <<
"Error writing to blockchain database: " << o.ToString();
634 blocksBatch.Iterate(&n);
635 cwarn <<
"Fail writing to blockchain database. Bombing out.";
642 cwarn <<
"Error writing to extras database: " << o.ToString();
644 extrasBatch.Iterate(&n);
645 cwarn <<
"Fail writing to extras database. Bombing out.";
654 #if ETH_TIMED_IMPORTS 656 double preliminaryChecks;
682 auto pdata = pd.
rlp();
698 BOOST_THROW_EXCEPTION(FutureTime());
706 #if ETH_TIMED_IMPORTS 707 preliminaryChecks = t.
elapsed();
711 ldb::WriteBatch blocksBatch;
712 ldb::WriteBatch extrasBatch;
714 unsigned newLastBlockNumber =
number();
728 auto tdIncrease = s.
enactOn(_block, *
this);
730 for (
unsigned i = 0; i < s.
pending().size(); ++i)
734 goodTransactions.push_back(s.
pending()[i]);
739 td = pd.totalDifficulty + tdIncrease;
741 #if ETH_TIMED_IMPORTS 744 #endif // ETH_TIMED_IMPORTS 748 #endif // ETH_PARANOIA 761 #if ETH_TIMED_IMPORTS 764 #endif // ETH_TIMED_IMPORTS 774 #if ETH_TIMED_IMPORTS 777 #endif // ETH_TIMED_IMPORTS 783 cwarn <<
"*** BadRoot error! Trying to import" << _block.
info.
hash() <<
"needed root" << ex.
root;
786 BOOST_THROW_EXCEPTION(TransientError());
802 bool isImportedAndBest =
false;
809 unsigned commonIndex;
811 route.push_back(_block.
info.
hash());
819 for (
auto i = route.rbegin(); i != route.rend() && *i != common; ++i)
834 for (
unsigned level = 0, index = (
unsigned)tbi.
number(); level < c_bloomIndexLevels; level++, index /= c_bloomIndexSize)
838 for (
unsigned level = 0, index = (
unsigned)tbi.
number(); level < c_bloomIndexLevels; level++, index /= c_bloomIndexSize)
840 unsigned i = index / c_bloomIndexSize;
841 unsigned o = index % c_bloomIndexSize;
842 alteredBlooms.push_back(
chunkId(level, i));
859 for (
auto const&
h: alteredBlooms)
866 newLastBlockHash = _block.
info.
hash();
867 newLastBlockNumber = (unsigned)_block.
info.
number();
868 isImportedAndBest =
true;
882 cwarn <<
"Error writing to blockchain database: " << o.ToString();
884 blocksBatch.Iterate(&n);
885 cwarn <<
"Fail writing to blockchain database. Bombing out.";
892 cwarn <<
"Error writing to extras database: " << o.ToString();
894 extrasBatch.Iterate(&n);
895 cwarn <<
"Fail writing to extras database. Bombing out.";
911 canary.populateFromChain(*
this, _block.
info.
hash());
920 #endif // ETH_PARANOIA 930 cwarn <<
"Error writing to extras database: " << o.ToString();
932 cwarn <<
"Fail writing to extras database. Bombing out.";
939 #endif // ETH_PARANOIA 941 #if ETH_TIMED_IMPORTS 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() <<
" }";
959 #endif // ETH_TIMED_IMPORTS 970 for (
auto const&
h: route)
977 return ImportRoute{dead, fresh, move(goodTransactions)};
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)
1003 for (
unsigned item = beginDirty; item != endDirty; ++item)
1005 unsigned bunch = item / c_bloomIndexSize;
1006 unsigned offset = item % c_bloomIndexSize;
1007 auto id =
chunkId(level, bunch);
1012 auto lowerChunkId =
chunkId(level - 1, item);
1024 cout <<
"Rescuing database..." << endl;
1041 cout <<
"Finding last likely block number..." << endl;
1044 unsigned m = (u + l) / 2;
1045 cout <<
" " << m << flush;
1051 cout <<
" lowest is " << l << endl;
1055 cout <<
"Checking validity of " << l <<
" (" << h <<
")..." << flush;
1058 cout <<
"block..." << flush;
1060 cout <<
"extras..." << flush;
1062 cout <<
"state..." << flush;
1068 cout <<
"OK." << endl;
1084 cwarn <<
"Error writing to extras database: " << o.ToString();
1086 cwarn <<
"Fail writing to extras database. Bombing out.";
1107 ret.push_back(from);
1123 if (_pre && (from != to || _common))
1124 ret.push_back(from);
1125 if (_post && (from != to || (!_pre && _common)))
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)
1141 return make_tuple(ret, from, i);
1146 auto id =
CacheID(_h, _extra);
1155 template <
class K,
class T>
static unsigned getHashSize(unordered_map<K, T>
const& _map)
1158 for (
auto const& i: _map)
1159 ret += i.second.size + 64;
1228 m_cacheUsage.push_front(std::unordered_set<CacheID>{});
1236 for (it->SeekToFirst(); it->Valid(); it->Next())
1237 if (it->key().size() == 32)
1246 cnote <<
"Apparently the database is corrupt. Not much we can do at this stage...";
1248 cnote <<
"Apparently the database is corrupt. Not much we can do at this stage...";
1256 unsigned end =
number() + 1;
1258 for (
auto i = _firstInvalid; i < end; ++i)
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; }
1286 vector<unsigned> ret;
1289 unsigned u = upow(c_bloomIndexSize, c_bloomIndexLevels);
1292 for (
unsigned index = _earliest / u; index <= ceilDiv(_latest, u); ++index)
1293 ret +=
withBlockBloom(_b, _earliest, _latest, c_bloomIndexLevels - 1, index);
1305 vector<unsigned> ret;
1307 unsigned uCourse = upow(c_bloomIndexSize, _level + 1);
1310 unsigned uFine = upow(c_bloomIndexSize, _level);
1314 unsigned obegin = _index == _earliest / uCourse ? _earliest / uFine % c_bloomIndexSize : 0;
1319 unsigned oend = _index == _latest / uCourse ? (_latest / uFine) % c_bloomIndexSize + 1 : c_bloomIndexSize;
1326 for (
unsigned o = obegin; o < oend; ++o)
1327 if (bb.blooms[o].contains(_b))
1331 ret +=
withBlockBloom(_b, _earliest, _latest, _level - 1, o + _index * c_bloomIndexSize);
1333 ret.push_back(o + _index * c_bloomIndexSize);
1346 ret.insert(
details(p).parent);
1348 for (
auto i:
RLP(b)[2])
1349 ret.insert(
sha3(i.data()));
1396 cwarn <<
"Couldn't find requested block:" << _hash;
1426 cwarn <<
"Couldn't find requested block:" << _hash;
1450 cwarn <<
"Hinted genesis block's state root hash is incorrect!";
1475 if (parentHeader.empty())
1499 for (
auto const& uncle: r[2])
1508 if (parentHeader.empty())
1522 if (!uh.extraData().empty())
1532 for (
RLP const& tr: r[1])
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
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
boost::error_info< struct tag_block, bytes > errinfo_block
static h256 chunkId(unsigned _level, unsigned _index)
std::string toHex(T const &_data, int _w=2, HexPrefix _prefix=HexPrefix::DontAdd)
#define function(a, b, c, d, k, s)
A modifiable reference to an existing object or vector in memory.
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)
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 ...
std::chrono::system_clock::time_point m_lastCollection
bytes genesisBlock() const
Genesis block info.
std::unordered_set< CacheID > m_inUse
bool doneDrain(h256s const &_knownBad=h256s())
Must be called after a drain() call.
void toBigEndian(T _val, Out &o_out)
Converts a templated integer value to the big-endian byte-stream represented on a templated collectio...
boost::error_info< struct tag_uncleIndex, unsigned > errinfo_uncleIndex
Implements the blockchain database.
bytes rlp(_T _t)
Export a single item in RLP format, returning a byte array.
bytesConstRef data() const
The bare data of the RLP.
bool exists(h256 const &_h) const
uint64_t utcTime()
Get the current time in seconds since the epoch in UTC.
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.
ldb::ReadOptions m_readOptions
LogBloom const & bloom() const
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...
std::unordered_map< std::string, std::string > otherParams
Additional parameters.
std::ostream & operator<<(std::ostream &_out, BlockHeader const &_bi)
void noteChain(BlockChain const &_bc)
Note the fact that this block is being used with a particular chain.
SharedMutex x_blocks
The caches of the disk DB and their locks.
boost::error_info< struct tag_transaction, bytes > errinfo_transaction
boost::error_info< struct tag_currentNumber, u256 > errinfo_currentNumber
std::vector< Transaction > Transactions
Nice name for vector of Transaction.
TransactionReceipts receipts
SharedMutex x_blockHashes
Do all checks that can be done independently of prior blocks having been imported.
LastHashes lastHashes() const
Get the last N hashes for a given block. (N is determined by the LastHashes type.) ...
void init(ChainParams const &_p)
Initialise everything and ready for openning the database.
boost::upgrade_to_unique_lock< boost::shared_mutex > UpgradeGuard
Block genesisBlock(OverlayDB const &_db) const
Get a pre-made genesis State object.
std::hash for asio::adress
assert(len-trim+(2 *lenIndices)<=WIDTH)
ldb::WriteOptions m_writeOptions
LastHashes m_lastLastHashes
Check the basic structure of the transactions.
std::string toString(string32 const &_s)
Make normal string from fixed-length string.
BlockLogBloomsHash m_logBlooms
vector_ref< _T > cropped(size_t _begin, size_t _count) const
boost::upgrade_lock< boost::shared_mutex > UpgradableGuard
#define DEV_TIMED_ABOVE(S, MS)
unsigned memTransactionAddresses
std::deque< std::unordered_set< CacheID > > m_cacheUsage
FixedHash & shiftBloom(FixedHash< M > const &_h)
BlocksBlooms blocksBlooms(unsigned _level, unsigned _index) const
Get the block blooms for a number of blocks.
BlockHeader const & genesis() const
Model of an Ethereum state, essentially a facade for the trie.
Require block to be non-genesis.
OverlayDB const & db() const
Verified block info, combines block data and verified info/transactions.
void close()
Finalise everything and close the database.
bytesConstRef block
Block data reference.
TransactionReceipt const & receipt(unsigned _i) const
Get the transaction receipt for the transaction of the given index.
boost::error_info< struct tag_phase, unsigned > errinfo_phase
u256 enactOn(VerifiedBlockRef const &_block, BlockChain const &_bc)
Execute all transactions within a given block.
std::shared_ptr< SealEngineFace > m_sealEngine
Active model of a block within the block chain.
boost::error_info< struct tag_hash, h256 > errinfo_hash256
void noteCanonChanged() const
boost::shared_mutex x_lastBlockHash
Hash of the last (valid) block on the longest chain.
std::vector< unsigned > withBlockBloom(LogBloom const &_b, unsigned _earliest, unsigned _latest) const
#define assertsEqual(A, B)
std::vector< h256 > LastHashes
Check the basic structure of the transactions.
Base class for all exceptions.
std::function< void(Exception &)> m_onBad
Called if we have a block that doesn't verify.
vector_ref< byte > bytesRef
std::string dumpDatabase() const
Gives a dump of the blockchain database. For debug/test use only.
void cleanup(bool _fullCommit)
Returns back to a pristine state after having done a playback.
std::lock_guard< std::mutex > Guard
SharedMutex x_blocksBlooms
bool contains(T const &_t, V const &_v)
std::shared_ptr< typename Signal< Args... >::HandlerAux > Handler
h256 numberHash(unsigned _i) const
Get the hash for a given block's number.
#define DEV_WRITE_GUARDED(MUTEX)
void rewind(unsigned _newHead)
Alter the head of the chain to some prior block along it.
boost::error_info< struct tag_required_h256, h256 > errinfo_required_h256
h256 currentHash() const
Get a given block (RLP format). Thread-safe.
#define DEV_READ_GUARDED(MUTEX)
std::vector< byte > bytes
std::vector< unsigned char > toBytes() const
vector_ref< byte const > bytesConstRef
BlockHeader m_previousBlock
The previous block's information.
void rebuild(std::string const &_path, ProgressCallback const &_progress=std::function< void(unsigned, unsigned)>())
Run through database and verify all blocks by reevaluating.
BlocksBloomsHash m_blocksBlooms
std::function< void(BlockHeader const &)> m_onBlockImport
Called if we have imported a new block into the db.
boost::error_info< struct tag_extraData, bytes > errinfo_extraData
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
void noteUsed(h256 const &_h, unsigned _extra=(unsigned)-1) const
boost::shared_lock< boost::shared_mutex > ReadGuard
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)...
BlockReceipts receipts() const
void resetCurrent(u256 const &_timestamp=u256(utcTime()))
Sets m_currentBlock to a clean state, (i.e.
Transactions const & pending() const
Get the list of pending transactions.
Encodes a transaction, ready to be exported to or freshly imported from RLP.
bytes m_genesisHeaderBytes
OverlayDB const & db() const
Open a DB - useful for passing into the constructor & keeping for other states that are necessary...
boost::unique_lock< boost::shared_mutex > WriteGuard
BlockHashHash m_blockHashes
void reopen(WithExisting _we=WithExisting::Trust, ProgressCallback const &_pc=ProgressCallback())
Reopen everything.
Check the basic structure of the uncles.
h256 rootHash() const
The hash of the root of our state tree.
ldb::Slice toSlice(h256 const &_h, unsigned _sub=0)
ImportRoute import(bytes const &_block, OverlayDB const &_stateDB, bool _mustBeNew=true)
Import block into disk-backed DB.
SecureTrieDB< Address, OverlayDB > m_state
Our state tree, as an OverlayDB DB.
State & mutableState()
Get a mutable State object which is backing this block.
SharedMutex x_transactionAddresses
void clearBlockBlooms(unsigned _begin, unsigned _end)
Check uncle parent block header.
Verified block info, does not hold block data, but a reference instead.
std::string toBigEndianString(u256 _val)
Convenience functions for toBigEndian.
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.
BlockReceiptsHash m_receipts
TransactionAddressHash m_transactionAddresses
Check the basic structure of the uncles.
ldb::DB * m_blocksDB
The disk DBs. Thread-safe, so no need for locks.
bool sha3(bytesConstRef _input, bytesRef o_output)
Calculate SHA3-256 hash of the given input and load it into the given output.
virtual void Put(ldb::Slice const &_key, ldb::Slice const &_value)
LogBloom blockBloom(unsigned _number) const
boost::error_info< struct tag_now, unsigned > errinfo_now
std::vector< VerifiedBlock > VerifiedBlocks
h256 genesisHash() const
Get the hash of the genesis block. Thread-safe.
std::vector< Transaction > transactions
Verified list of block transactions.
unsigned m_lastBlockNumber
std::unordered_set< h256 > h256Hash
const unsigned c_databaseVersion
Current database version.
void insert(bytes const &_block, bytesConstRef _receipts, bool _mustBeNew=true)
Import data into disk-backed DB.
h256 orderedTrieRoot(std::vector< bytes > const &_data)
boost::error_info< struct tag_transactionIndex, unsigned > errinfo_transactionIndex
Do all checks that cannot be done independently of prior blocks having been imported.
virtual void Delete(ldb::Slice const &_key)
AddressHash commit(AccountMap const &_cache, SecureTrieDB< Address, DB > &_state)
std::tuple< ImportRoute, bool, unsigned > sync(BlockQueue &_bq, OverlayDB const &_stateDB, unsigned _max)
Sync the chain with any incoming blocks.
boost::error_info< struct tag_uncleNumber, u256 > errinfo_uncleNumber
Check parent block header.
std::vector< Transaction > goodTranactions
std::vector< h256 > h256s
SealEngineFace * createSealEngine()
void rescue(OverlayDB const &_db)
Rescue the database.
BlockHeader info
Prepopulated block info.
bytes contents(std::string const &_file)
Retrieve and returns the contents of the given file.
unsigned open(std::string const &_path, WithExisting _we)
Open the database.
Class for interpreting Recursive Linear-Prefix Data.
#define DEV_IGNORE_EXCEPTIONS(X)
BlockDetails details() const
std::function< void(unsigned, unsigned)> ProgressCallback
virtual void verify(Strictness _s, BlockHeader const &_bi, BlockHeader const &_parent=BlockHeader(), bytesConstRef _block=bytesConstRef()) const
Don't forget to call Super::verify when subclassing & overriding.
unsigned memTotal() const
SealEngineFace * sealEngine() const
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.
LogBloom bloom(LogEntries const &_logs)
BlockDetailsHash m_details
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...