From 9038430a2da2a3108f296bd3434de49c0a884d6c Mon Sep 17 00:00:00 2001 From: Matthew Wampler-Doty Date: Wed, 11 Mar 2015 23:45:34 -0700 Subject: [PATCH] Introducing bounds checking, DOS quick verification --- libethash/ethash.h | 6 +++--- libethash/internal.h | 6 ------ libethcore/Ethasher.cpp | 19 +++++++++++++++++-- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/libethash/ethash.h b/libethash/ethash.h index 918a77413..bc2f528ed 100644 --- a/libethash/ethash.h +++ b/libethash/ethash.h @@ -82,11 +82,11 @@ static inline int ethash_check_difficulty( return 1; } -int ethash_quick_check_difficulty( +void ethash_quick_hash( + uint8_t return_hash[32], const uint8_t header_hash[32], const uint64_t nonce, - const uint8_t mix_hash[32], - const uint8_t difficulty[32]); + const uint8_t mix_hash[32]); #ifdef __cplusplus } diff --git a/libethash/internal.h b/libethash/internal.h index bcbacdaa4..d77991d56 100644 --- a/libethash/internal.h +++ b/libethash/internal.h @@ -37,12 +37,6 @@ void ethash_calculate_dag_item( ethash_cache const *cache ); -void ethash_quick_hash( - uint8_t return_hash[32], - const uint8_t header_hash[32], - const uint64_t nonce, - const uint8_t mix_hash[32]); - #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/libethcore/Ethasher.cpp b/libethcore/Ethasher.cpp index a28895a1a..bfaed4c7d 100644 --- a/libethcore/Ethasher.cpp +++ b/libethcore/Ethasher.cpp @@ -43,6 +43,12 @@ Ethasher* dev::eth::Ethasher::s_this = nullptr; bytes const& Ethasher::cache(BlockInfo const& _header) { RecursiveGuard l(x_this); + if (_header.number > EPOCH_LENGTH*2048) { + std::ostringstream error; + error << "block number is too high; max is " << EPOCH_LENGTH*2048 << "(was " << _header.number << ")"; + throw std::invalid_argument( error.str() ); + } + if (!m_caches.count(_header.seedHash)) { try { @@ -100,7 +106,17 @@ ethash_params Ethasher::params(unsigned _n) bool Ethasher::verify(BlockInfo const& _header) { + if (_header.number >= EPOCH_LENGTH * 2048) return false; bigint boundary = (bigint(1) << 256) / _header.difficulty; + uint8_t quick_hash_out[32]; + ethash_quick_hash( + quick_hash_out, + _header.headerHash(WithoutNonce).data(), + (uint64_t) (u64) _header.nonce, + _header.mixHash.data() + ); + h256 quick_hash_out256 = h256(quick_hash_out, h256::ConstructFromPointer); + if (quick_hash_out256 > boundary) return false; auto e = eval(_header, _header.nonce); return (u256)e.value <= boundary && e.mixHash == _header.mixHash; } @@ -111,5 +127,4 @@ Ethasher::Result Ethasher::eval(BlockInfo const& _header, Nonce const& _nonce) ethash_return_value r; ethash_compute_light(&r, Ethasher::get()->cache(_header).data(), &p, _header.headerHash(WithoutNonce).data(), (uint64_t)(u64)_nonce); return Result{h256(r.result, h256::ConstructFromPointer), h256(r.mix_hash, h256::ConstructFromPointer)}; -} - +} \ No newline at end of file