diff --git a/libethcore/Common.cpp b/libethcore/Common.cpp index 02e806905..572ade3e2 100644 --- a/libethcore/Common.cpp +++ b/libethcore/Common.cpp @@ -36,7 +36,7 @@ namespace eth const unsigned c_ethashVersion = c_ethashRevision; const unsigned c_protocolVersion = 60; const unsigned c_minorProtocolVersion = 0; -const unsigned c_databaseBaseVersion = 8; +const unsigned c_databaseBaseVersion = 9; #if ETH_FATDB const unsigned c_databaseVersionModifier = 1; #else diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp index cad23171a..74aeb4fad 100644 --- a/libethereum/BlockChain.cpp +++ b/libethereum/BlockChain.cpp @@ -21,6 +21,9 @@ #include "BlockChain.h" +#if ETH_PROFILING_GPERF +#include +#endif #include #include #include @@ -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> 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 #define IGNORE_EXCEPTIONS(X) try { X; } catch (...) {} void BlockChain::rebuild(std::string const& _path, std::function const& _progress) @@ -187,6 +204,7 @@ void BlockChain::rebuild(std::string const& _path, std::functionsecond; + } + + 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]; +} diff --git a/libethereum/BlockChain.h b/libethereum/BlockChain.h index 2e2d8cf34..83b1926e8 100644 --- a/libethereum/BlockChain.h +++ b/libethereum/BlockChain.h @@ -64,6 +64,7 @@ struct BlockChainWarn: public LogChannel { static const char* name() { return "= std::map const& genesisState(); ldb::Slice toSlice(h256 const& _h, unsigned _sub = 0); +ldb::Slice oldToSlice(h256 const& _h, unsigned _sub = 0); using BlocksHash = std::map; using TransactionHashes = h256s; @@ -119,6 +120,7 @@ public: /// Get a block (RLP format) for the given hash (or the most recent mined if none given). Thread-safe. bytes block(h256 const& _hash) const; bytes block() const { return block(currentHash()); } + bytes oldBlock(h256 const& _hash) const; /// Get the familial details concerning a block (or the most recent mined if none given). Thread-safe. BlockDetails details(h256 const& _hash) const { return queryExtras(_hash, m_details, x_details, NullBlockDetails); } @@ -268,6 +270,30 @@ private: return ret.first->second; } + template T oldQueryExtras(h256 const& _h, std::map& _m, boost::shared_mutex& _x, T const& _n, ldb::DB* _extrasDB = nullptr) const + { + { + ReadGuard l(_x); + auto it = _m.find(_h); + if (it != _m.end()) + return it->second; + } + + std::string s; + (_extrasDB ? _extrasDB : m_extrasDB)->Get(m_readOptions, oldToSlice(_h, N), &s); + if (s.empty()) + { +// cout << "Not found in DB: " << _h << endl; + return _n; + } + + noteUsed(_h, N); + + WriteGuard l(_x); + auto ret = _m.insert(std::make_pair(_h, T(RLP(s)))); + return ret.first->second; + } + void checkConsistency(); /// The caches of the disk DB and their locks. diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 95fd2364f..71a9a4dbe 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -123,7 +123,7 @@ Client::Client(p2p::Host* _extNet, std::string const& _dbPath, WithExisting _for m_bc(_dbPath, max(m_vc.action(), _forceAction), [](unsigned d, unsigned t){ cerr << "REVISING BLOCKCHAIN: Processed " << d << " of " << t << "...\r"; }), m_gp(new TrivialGasPricer), m_stateDB(State::openDB(_dbPath, max(m_vc.action(), _forceAction))), - m_preMine(m_stateDB), + m_preMine(m_stateDB, BaseState::CanonGenesis), m_postMine(m_stateDB) { m_gp->update(m_bc); diff --git a/libethereum/EthereumPeer.cpp b/libethereum/EthereumPeer.cpp index 15ce5c3f6..ca0195efe 100644 --- a/libethereum/EthereumPeer.cpp +++ b/libethereum/EthereumPeer.cpp @@ -478,7 +478,12 @@ bool EthereumPeer::interpret(unsigned _id, RLP const& _r) clogS(NetMessageSummary) << dec << success << "imported OK," << unknown << "with unknown parents," << future << "with future timestamps," << got << " already known," << repeated << " repeats received."; if (m_asking == Asking::Blocks) - transition(Asking::Blocks); + { + if (!got) + transition(Asking::Blocks); + else + transition(Asking::Nothing); + } break; } case NewBlockPacket: