From 9450a7c4630b5398b4365a109c12e3d35428940b Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Wed, 15 Apr 2015 13:48:03 +0200 Subject: [PATCH] Cleanup light, full caches are removed automatically without making mining slow. --- eth/main.cpp | 2 +- libethcore/EthashAux.cpp | 65 +++++++++++++++++++++++++--------------- libethcore/EthashAux.h | 27 ++++++++++++----- 3 files changed, 62 insertions(+), 32 deletions(-) diff --git a/eth/main.cpp b/eth/main.cpp index 98d98b2ab..bdd3000a2 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -672,7 +672,7 @@ int main(int argc, char** argv) cout << " with seed as " << seedHash << endl; if (valid) cout << "(mixHash = " << r.mixHash << ")" << endl; - cout << "SHA3( light(seed) ) = " << sha3(bytesConstRef((byte const*)EthashAux::light(seedHash), EthashAux::params(seedHash).cache_size)) << endl; + cout << "SHA3( light(seed) ) = " << sha3(EthashAux::light(seedHash)->data()) << endl; exit(0); } catch (...) diff --git a/libethcore/EthashAux.cpp b/libethcore/EthashAux.cpp index 3b52d39f6..1af263396 100644 --- a/libethcore/EthashAux.cpp +++ b/libethcore/EthashAux.cpp @@ -46,8 +46,6 @@ EthashAux* dev::eth::EthashAux::s_this = nullptr; EthashAux::~EthashAux() { - while (!m_lights.empty()) - killCache(m_lights.begin()->first); } ethash_params EthashAux::params(BlockInfo const& _header) @@ -112,29 +110,34 @@ ethash_params EthashAux::params(h256 const& _seedHash) void EthashAux::killCache(h256 const& _s) { RecursiveGuard l(x_this); - if (m_lights.count(_s)) - { - ethash_delete_light(m_lights.at(_s)); - m_lights.erase(_s); - } + m_lights.erase(_s); } -void const* EthashAux::light(BlockInfo const& _header) +EthashAux::LightType EthashAux::light(BlockInfo const& _header) { return light(_header.seedHash()); } -void const* EthashAux::light(h256 const& _seedHash) +EthashAux::LightType EthashAux::light(h256 const& _seedHash) { RecursiveGuard l(get()->x_this); - if (!get()->m_lights.count(_seedHash)) - { - ethash_params p = params(_seedHash); - get()->m_lights[_seedHash] = ethash_new_light(&p, _seedHash.data()); - } - return get()->m_lights[_seedHash]; + LightType ret = get()->m_lights[_seedHash]; + return ret ? ret : (get()->m_lights[_seedHash] = make_shared(_seedHash)); +} + +EthashAux::LightAllocation::LightAllocation(h256 const& _seed) +{ + auto p = params(_seed); + size = p.cache_size; + light = ethash_new_light(&p, _seed.data()); +} + +EthashAux::LightAllocation::~LightAllocation() +{ + ethash_delete_light(light); } + EthashAux::FullType EthashAux::full(BlockInfo const& _header, bytesRef _dest) { return full(_header.seedHash(), _dest); @@ -152,6 +155,9 @@ EthashAux::FullType EthashAux::full(h256 const& _seedHash, bytesRef _dest) } if (!ret) { + // drop our last used cache sine we're allocating another 1GB. + get()->m_lastUsedFull.reset(); + try { boost::filesystem::create_directories(getDataDir("ethash")); } catch (...) {} @@ -180,14 +186,15 @@ EthashAux::FullType EthashAux::full(h256 const& _seedHash, bytesRef _dest) r = _dest; else r = bytesRef(new byte[p.full_size], p.full_size); - ethash_prep_full(r.data(), &p, light(_seedHash)); + ethash_prep_full(r.data(), &p, light(_seedHash)->light); writeFile(memoFile, r); } if (_dest) return FullType(); - ret = make_shared(r); + ret = make_shared(r); get()->m_fulls[_seedHash] = ret; } + get()->m_lastUsedFull = ret; return ret; } @@ -196,15 +203,25 @@ Ethash::Result EthashAux::eval(BlockInfo const& _header, Nonce const& _nonce) return eval(_header.seedHash(), _header.headerHash(WithoutNonce), _nonce); } -Ethash::Result EthashAux::eval(h256 const& _seedHash, h256 const& _headerHash, Nonce const& _nonce) +Ethash::Result EthashAux::FullAllocation::compute(h256 const& _seedHash, h256 const& _headerHash, Nonce const& _nonce) const { + ethash_return_value r; auto p = EthashAux::params(_seedHash); + ethash_compute_full(&r, data.data(), &p, _headerHash.data(), (uint64_t)(u64)_nonce); + return Ethash::Result{h256(r.result, h256::ConstructFromPointer), h256(r.mix_hash, h256::ConstructFromPointer)}; +} + +Ethash::Result EthashAux::LightAllocation::compute(h256 const& _seedHash, h256 const& _headerHash, Nonce const& _nonce) const +{ ethash_return_value r; - auto dag = EthashAux::get()->full(_seedHash); - if (EthashAux::get()->m_fulls.count(_seedHash)) - ethash_compute_full(&r, dag->data.data(), &p, _headerHash.data(), (uint64_t)(u64)_nonce); - else - ethash_compute_light(&r, EthashAux::get()->light(_seedHash), &p, _headerHash.data(), (uint64_t)(u64)_nonce); -// cdebug << "EthashAux::eval sha3(cache):" << sha3(EthashAux::get()->cache(_header)) << "hh:" << _header.headerHash(WithoutNonce) << "nonce:" << _nonce << " => " << h256(r.result, h256::ConstructFromPointer); + auto p = EthashAux::params(_seedHash); + ethash_compute_light(&r, light, &p, _headerHash.data(), (uint64_t)(u64)_nonce); return Ethash::Result{h256(r.result, h256::ConstructFromPointer), h256(r.mix_hash, h256::ConstructFromPointer)}; } + +Ethash::Result EthashAux::eval(h256 const& _seedHash, h256 const& _headerHash, Nonce const& _nonce) +{ + if (auto dag = EthashAux::get()->full(_seedHash)) + return dag->compute(_seedHash, _headerHash, _nonce); + return EthashAux::get()->light(_seedHash)->compute(_seedHash, _headerHash, _nonce); +} diff --git a/libethcore/EthashAux.h b/libethcore/EthashAux.h index 6322ffd8f..98a6554ad 100644 --- a/libethcore/EthashAux.h +++ b/libethcore/EthashAux.h @@ -33,14 +33,26 @@ public: static EthashAux* get() { if (!s_this) s_this = new EthashAux(); return s_this; } - struct FullTypeAllocation + struct FullAllocation { - FullTypeAllocation(bytesConstRef _d): data(_d) {} - ~FullTypeAllocation() { delete [] data.data(); } + FullAllocation(bytesConstRef _d): data(_d) {} + ~FullAllocation() { delete [] data.data(); } + Ethash::Result compute(h256 const& _seedHash, h256 const& _headerHash, Nonce const& _nonce) const; bytesConstRef const data; }; - using LightType = void const*; - using FullType = std::shared_ptr; + + struct LightAllocation + { + LightAllocation(h256 const& _seed); + ~LightAllocation(); + bytesConstRef data() const { return bytesConstRef((byte const*)light, size); } + Ethash::Result compute(h256 const& _seedHash, h256 const& _headerHash, Nonce const& _nonce) const; + ethash_light_t light; + uint64_t size; + }; + + using LightType = std::shared_ptr; + using FullType = std::shared_ptr; static h256 seedHash(unsigned _number); static ethash_params params(BlockInfo const& _header); @@ -63,8 +75,9 @@ private: static EthashAux* s_this; RecursiveMutex x_this; - std::map m_lights; - std::map> m_fulls; + std::map> m_lights; + std::map> m_fulls; + FullType m_lastUsedFull; std::map m_epochs; h256s m_seedHashes; };