|
|
@ -21,6 +21,9 @@ |
|
|
|
|
|
|
|
#include "BlockChain.h" |
|
|
|
|
|
|
|
#if ETH_PROFILING_GPERF |
|
|
|
#include <gperftools/profiler.h> |
|
|
|
#endif |
|
|
|
#include <leveldb/db.h> |
|
|
|
#include <boost/timer.hpp> |
|
|
|
#include <boost/filesystem.hpp> |
|
|
@ -65,7 +68,7 @@ std::ostream& dev::eth::operator<<(std::ostream& _out, BlockChain const& _bc) |
|
|
|
return _out; |
|
|
|
} |
|
|
|
|
|
|
|
ldb::Slice dev::eth::toSlice(h256 const& _h, unsigned _sub) |
|
|
|
ldb::Slice dev::eth::oldToSlice(h256 const& _h, unsigned _sub) |
|
|
|
{ |
|
|
|
#if ALL_COMPILERS_ARE_CPP11_COMPLIANT |
|
|
|
static thread_local h256 h = _h ^ sha3(h256(u256(_sub))); |
|
|
@ -79,6 +82,21 @@ ldb::Slice dev::eth::toSlice(h256 const& _h, unsigned _sub) |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
ldb::Slice dev::eth::toSlice(h256 const& _h, unsigned _sub) |
|
|
|
{ |
|
|
|
#if ALL_COMPILERS_ARE_CPP11_COMPLIANT |
|
|
|
static thread_local h256 h = _h ^ sha3(h256(u256(_sub))); |
|
|
|
return ldb::Slice((char const*)&h, 32); |
|
|
|
#else |
|
|
|
static boost::thread_specific_ptr<FixedHash<33>> t_h; |
|
|
|
if (!t_h.get()) |
|
|
|
t_h.reset(new FixedHash<33>); |
|
|
|
*t_h = FixedHash<33>(_h); |
|
|
|
(*t_h)[32] = (uint8_t)_sub; |
|
|
|
return (ldb::Slice)t_h->ref();//(char const*)t_h.get(), 32);
|
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
#if ETH_DEBUG |
|
|
|
static const chrono::system_clock::duration c_collectionDuration = chrono::seconds(15); |
|
|
|
static const unsigned c_collectionQueueSize = 2; |
|
|
@ -148,7 +166,7 @@ void BlockChain::open(std::string const& _path, WithExisting _we) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (!details(m_genesisHash)) |
|
|
|
if (_we != WithExisting::Verify && !details(m_genesisHash)) |
|
|
|
{ |
|
|
|
// Insert details of genesis block.
|
|
|
|
m_details[m_genesisHash] = BlockDetails(0, c_genesisDifficulty, h256(), {}); |
|
|
@ -178,7 +196,6 @@ void BlockChain::close() |
|
|
|
m_blocks.clear(); |
|
|
|
} |
|
|
|
|
|
|
|
#include <gperftools/profiler.h> |
|
|
|
#define IGNORE_EXCEPTIONS(X) try { X; } catch (...) {} |
|
|
|
|
|
|
|
void BlockChain::rebuild(std::string const& _path, std::function<void(unsigned, unsigned)> const& _progress) |
|
|
@ -187,6 +204,7 @@ void BlockChain::rebuild(std::string const& _path, std::function<void(unsigned, |
|
|
|
ProfilerStart("BlockChain_rebuild.log"); |
|
|
|
#endif |
|
|
|
|
|
|
|
// unsigned originalNumber = (unsigned)BlockInfo(oldBlock(m_lastBlockHash)).number;
|
|
|
|
unsigned originalNumber = number(); |
|
|
|
|
|
|
|
// Keep extras DB around, but under a temp name
|
|
|
@ -968,3 +986,33 @@ bytes BlockChain::block(h256 const& _hash) const |
|
|
|
|
|
|
|
return m_blocks[_hash]; |
|
|
|
} |
|
|
|
|
|
|
|
bytes BlockChain::oldBlock(h256 const& _hash) const |
|
|
|
{ |
|
|
|
if (_hash == m_genesisHash) |
|
|
|
return m_genesisBlock; |
|
|
|
|
|
|
|
{ |
|
|
|
ReadGuard l(x_blocks); |
|
|
|
auto it = m_blocks.find(_hash); |
|
|
|
if (it != m_blocks.end()) |
|
|
|
return it->second; |
|
|
|
} |
|
|
|
|
|
|
|
string d; |
|
|
|
m_blocksDB->Get(m_readOptions, oldToSlice(_hash), &d); |
|
|
|
|
|
|
|
if (!d.size()) |
|
|
|
{ |
|
|
|
cwarn << "Couldn't find requested block:" << _hash.abridged(); |
|
|
|
return bytes(); |
|
|
|
} |
|
|
|
|
|
|
|
WriteGuard l(x_blocks); |
|
|
|
m_blocks[_hash].resize(d.size()); |
|
|
|
memcpy(m_blocks[_hash].data(), d.data(), d.size()); |
|
|
|
|
|
|
|
noteUsed(_hash); |
|
|
|
|
|
|
|
return m_blocks[_hash]; |
|
|
|
} |
|
|
|