Browse Source

For Marek :)

BlockChain::transaction(h256 _transactionHash)
BlockChain::transactionHashes(h256 _blockHash)
cl-refactor
Gav Wood 10 years ago
parent
commit
e36bb27269
  1. 5
      alethzero/MainWin.cpp
  2. 1
      libethcore/BlockInfo.h
  3. 115
      libethcore/Ethasher.cpp
  4. 97
      libethcore/Ethasher.h
  5. 98
      libethcore/ProofOfWork.cpp
  6. 10
      libethcore/ProofOfWork.h
  7. 6
      libethereum/BlockChain.cpp
  8. 14
      libethereum/BlockChain.h
  9. 14
      libethereum/BlockDetails.h
  10. 76
      test/dagger.cpp

5
alethzero/MainWin.cpp

@ -40,6 +40,7 @@
#endif #endif
#include <libdevcrypto/FileSystem.h> #include <libdevcrypto/FileSystem.h>
#include <libethcore/CommonJS.h> #include <libethcore/CommonJS.h>
#include <libethcore/Ethasher.h>
#include <liblll/Compiler.h> #include <liblll/Compiler.h>
#include <liblll/CodeFragment.h> #include <liblll/CodeFragment.h>
#include <libsolidity/Scanner.h> #include <libsolidity/Scanner.h>
@ -1369,7 +1370,7 @@ void Main::on_blocks_currentItemChanged()
s << "<br/>Difficulty: <b>" << info.difficulty << "</b>"; s << "<br/>Difficulty: <b>" << info.difficulty << "</b>";
if (info.number) if (info.number)
{ {
auto e = ProofOfWork::eval(info); auto e = Ethasher::eval(info);
s << "<br/>Proof-of-Work: <b>" << e.value << " &lt;= " << (h256)u256((bigint(1) << 256) / info.difficulty) << "</b> (mixhash: " << e.mixHash.abridged() << ")"; s << "<br/>Proof-of-Work: <b>" << e.value << " &lt;= " << (h256)u256((bigint(1) << 256) / info.difficulty) << "</b> (mixhash: " << e.mixHash.abridged() << ")";
} }
else else
@ -1393,7 +1394,7 @@ void Main::on_blocks_currentItemChanged()
s << line << "Nonce: <b>" << uncle.nonce << "</b>"; s << line << "Nonce: <b>" << uncle.nonce << "</b>";
s << line << "Hash w/o nonce: <b>" << uncle.headerHash(WithoutNonce) << "</b>"; s << line << "Hash w/o nonce: <b>" << uncle.headerHash(WithoutNonce) << "</b>";
s << line << "Difficulty: <b>" << uncle.difficulty << "</b>"; s << line << "Difficulty: <b>" << uncle.difficulty << "</b>";
auto e = ProofOfWork::eval(uncle); auto e = Ethasher::eval(uncle);
s << line << "Proof-of-Work: <b>" << e.value << " &lt;= " << (h256)u256((bigint(1) << 256) / uncle.difficulty) << "</b> (mixhash: " << e.mixHash.abridged() << ")"; s << line << "Proof-of-Work: <b>" << e.value << " &lt;= " << (h256)u256((bigint(1) << 256) / uncle.difficulty) << "</b> (mixhash: " << e.mixHash.abridged() << ")";
} }
if (info.parentHash) if (info.parentHash)

1
libethcore/BlockInfo.h

@ -85,6 +85,7 @@ public:
static h256 headerHash(bytes const& _block) { return headerHash(&_block); } static h256 headerHash(bytes const& _block) { return headerHash(&_block); }
static h256 headerHash(bytesConstRef _block); static h256 headerHash(bytesConstRef _block);
static BlockInfo fromHeader(bytes const& _block) { return fromHeader(bytesConstRef(&_block)); }
static BlockInfo fromHeader(bytesConstRef _block); static BlockInfo fromHeader(bytesConstRef _block);
explicit operator bool() const { return timestamp != Invalid256; } explicit operator bool() const { return timestamp != Invalid256; }

115
libethcore/Ethasher.cpp

@ -0,0 +1,115 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file Ethasher.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#include <boost/detail/endian.hpp>
#include <boost/filesystem.hpp>
#include <chrono>
#include <array>
#include <random>
#include <thread>
#include <libdevcore/Guards.h>
#include <libdevcore/Log.h>
#include <libdevcrypto/CryptoPP.h>
#include <libdevcrypto/FileSystem.h>
#include <libdevcore/Common.h>
#include <libethash/ethash.h>
#include "BlockInfo.h"
#include "Ethasher.h"
using namespace std;
using namespace chrono;
using namespace dev;
using namespace eth;
Ethasher* dev::eth::Ethasher::s_this = nullptr;
bytes const& Ethasher::cache(BlockInfo const& _header)
{
RecursiveGuard l(x_this);
if (!m_caches.count(_header.seedHash))
{
try {
boost::filesystem::create_directories(getDataDir() + "/ethashcache");
} catch (...) {}
std::string memoFile = getDataDir() + "/ethashcache/" + toHex(_header.seedHash.ref().cropped(0, 4)) + ".cache";
m_caches[_header.seedHash] = contents(memoFile);
if (m_caches[_header.seedHash].empty())
{
ethash_params p = params((unsigned)_header.number);
m_caches[_header.seedHash].resize(p.cache_size);
ethash_prep_light(m_caches[_header.seedHash].data(), &p, _header.seedHash.data());
writeFile(memoFile, m_caches[_header.seedHash]);
}
}
return m_caches[_header.seedHash];
}
bytesConstRef Ethasher::full(BlockInfo const& _header)
{
RecursiveGuard l(x_this);
if (!m_fulls.count(_header.seedHash))
{
if (!m_fulls.empty())
{
delete [] m_fulls.begin()->second.data();
m_fulls.erase(m_fulls.begin());
}
std::string memoFile = getDataDir() + "/ethashcache/" + toHex(_header.seedHash.ref().cropped(0, 4)) + ".full";
m_fulls[_header.seedHash] = contentsNew(memoFile);
if (!m_fulls[_header.seedHash])
{
ethash_params p = params((unsigned)_header.number);
m_fulls[_header.seedHash] = bytesRef(new byte[p.full_size], p.full_size);
auto c = cache(_header);
ethash_prep_full(m_fulls[_header.seedHash].data(), &p, c.data());
writeFile(memoFile, m_fulls[_header.seedHash]);
}
}
return m_fulls[_header.seedHash];
}
ethash_params Ethasher::params(BlockInfo const& _header)
{
return params((unsigned)_header.number);
}
ethash_params Ethasher::params(unsigned _n)
{
ethash_params p;
p.cache_size = ethash_get_cachesize(_n);
p.full_size = ethash_get_datasize(_n);
return p;
}
bool Ethasher::verify(BlockInfo const& _header)
{
bigint boundary = (bigint(1) << 256) / _header.difficulty;
auto e = eval(_header, _header.nonce);
return (u256)e.value <= boundary && e.mixHash == _header.mixHash;
}
Ethasher::Result Ethasher::eval(BlockInfo const& _header, Nonce const& _nonce)
{
auto p = Ethasher::params(_header);
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)};
}

97
libethcore/Ethasher.h

@ -0,0 +1,97 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file Ethasher.h
* @author Gav Wood <i@gavwood.com>
* @date 2014
*
* ProofOfWork algorithm.
*/
#pragma once
#include <chrono>
#include <thread>
#include <cstdint>
#include <libdevcore/Guards.h>
#include <libdevcrypto/SHA3.h>
#include <libethash/ethash.h> // TODO: REMOVE once everything merged into this class and an opaque API can be provided.
#include "Common.h"
#include "BlockInfo.h"
namespace dev
{
namespace eth
{
class Ethasher
{
public:
Ethasher() {}
static Ethasher* get() { if (!s_this) s_this = new Ethasher(); return s_this; }
bytes const& cache(BlockInfo const& _header);
bytesConstRef full(BlockInfo const& _header);
static ethash_params params(BlockInfo const& _header);
static ethash_params params(unsigned _n);
struct Result
{
h256 value;
h256 mixHash;
};
static Result eval(BlockInfo const& _header) { return eval(_header, _header.nonce); }
static Result eval(BlockInfo const& _header, Nonce const& _nonce);
static bool verify(BlockInfo const& _header);
class Miner
{
public:
Miner(BlockInfo const& _header):
m_headerHash(_header.headerHash(WithoutNonce)),
m_params(Ethasher::params(_header)),
m_datasetPointer(Ethasher::get()->full(_header).data())
{}
inline h256 mine(uint64_t _nonce)
{
ethash_compute_full(&m_ethashReturn, m_datasetPointer, &m_params, m_headerHash.data(), _nonce);
return h256(m_ethashReturn.result, h256::ConstructFromPointer);
}
inline h256 lastMixHash() const
{
return h256(m_ethashReturn.mix_hash, h256::ConstructFromPointer);
}
private:
ethash_return_value m_ethashReturn;
h256 m_headerHash;
ethash_params m_params;
void const* m_datasetPointer;
};
private:
static Ethasher* s_this;
RecursiveMutex x_this;
std::map<h256, bytes> m_caches;
std::map<h256, bytesRef> m_fulls;
};
}
}

98
libethcore/ProofOfWork.cpp

@ -30,8 +30,8 @@
#include <libdevcrypto/CryptoPP.h> #include <libdevcrypto/CryptoPP.h>
#include <libdevcrypto/FileSystem.h> #include <libdevcrypto/FileSystem.h>
#include <libdevcore/Common.h> #include <libdevcore/Common.h>
#include <libethash/ethash.h>
#include "BlockInfo.h" #include "BlockInfo.h"
#include "Ethasher.h"
#include "ProofOfWork.h" #include "ProofOfWork.h"
using namespace std; using namespace std;
using namespace std::chrono; using namespace std::chrono;
@ -41,100 +41,14 @@ namespace dev
namespace eth namespace eth
{ {
class Ethasher
{
public:
Ethasher() {}
static Ethasher* get() { if (!s_this) s_this = new Ethasher(); return s_this; }
bytes const& cache(BlockInfo const& _header)
{
RecursiveGuard l(x_this);
if (!m_caches.count(_header.seedHash))
{
try {
boost::filesystem::create_directories(getDataDir() + "/ethashcache");
} catch (...) {}
std::string memoFile = getDataDir() + "/ethashcache/" + toHex(_header.seedHash.ref().cropped(0, 4)) + ".cache";
m_caches[_header.seedHash] = contents(memoFile);
if (m_caches[_header.seedHash].empty())
{
ethash_params p = params((unsigned)_header.number);
m_caches[_header.seedHash].resize(p.cache_size);
ethash_prep_light(m_caches[_header.seedHash].data(), &p, _header.seedHash.data());
writeFile(memoFile, m_caches[_header.seedHash]);
}
}
return m_caches[_header.seedHash];
}
byte const* full(BlockInfo const& _header)
{
RecursiveGuard l(x_this);
if (!m_fulls.count(_header.seedHash))
{
if (!m_fulls.empty())
{
delete [] m_fulls.begin()->second.data();
m_fulls.erase(m_fulls.begin());
}
std::string memoFile = getDataDir() + "/ethashcache/" + toHex(_header.seedHash.ref().cropped(0, 4)) + ".full";
m_fulls[_header.seedHash] = contentsNew(memoFile);
if (!m_fulls[_header.seedHash])
{
ethash_params p = params((unsigned)_header.number);
m_fulls[_header.seedHash] = bytesRef(new byte[p.full_size], p.full_size);
auto c = cache(_header);
ethash_prep_full(m_fulls[_header.seedHash].data(), &p, c.data());
writeFile(memoFile, m_fulls[_header.seedHash]);
}
}
return m_fulls[_header.seedHash].data();
}
static ethash_params params(BlockInfo const& _header)
{
return params((unsigned)_header.number);
}
static ethash_params params(unsigned _n)
{
ethash_params p;
p.cache_size = ethash_get_cachesize(_n);
p.full_size = ethash_get_datasize(_n);
return p;
}
private:
static Ethasher* s_this;
RecursiveMutex x_this;
std::map<h256, bytes> m_caches;
std::map<h256, bytesRef> m_fulls;
};
Ethasher* Ethasher::s_this = nullptr;
bool Ethash::verify(BlockInfo const& _header) bool Ethash::verify(BlockInfo const& _header)
{ {
bigint boundary = (bigint(1) << 256) / _header.difficulty; return Ethasher::verify(_header);
auto e = eval(_header, _header.nonce);
return (u256)e.value <= boundary && e.mixHash == _header.mixHash;
}
Ethash::Result Ethash::eval(BlockInfo const& _header, Nonce const& _nonce)
{
auto p = Ethasher::params(_header);
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)};
} }
std::pair<MineInfo, Ethash::Proof> Ethash::mine(BlockInfo const& _header, unsigned _msTimeout, bool _continue, bool _turbo) std::pair<MineInfo, Ethash::Proof> Ethash::mine(BlockInfo const& _header, unsigned _msTimeout, bool _continue, bool _turbo)
{ {
auto h = _header.headerHash(WithoutNonce); Ethasher::Miner m(_header);
auto p = Ethasher::params(_header);
auto d = Ethasher::get()->full(_header);
std::pair<MineInfo, Proof> ret; std::pair<MineInfo, Proof> ret;
static std::mt19937_64 s_eng((time(0) + *reinterpret_cast<unsigned*>(m_last.data()))); static std::mt19937_64 s_eng((time(0) + *reinterpret_cast<unsigned*>(m_last.data())));
@ -152,17 +66,15 @@ std::pair<MineInfo, Ethash::Proof> Ethash::mine(BlockInfo const& _header, unsign
std::this_thread::sleep_for(std::chrono::milliseconds(_msTimeout * 90 / 100)); std::this_thread::sleep_for(std::chrono::milliseconds(_msTimeout * 90 / 100));
double best = 1e99; // high enough to be effectively infinity :) double best = 1e99; // high enough to be effectively infinity :)
Proof result; Proof result;
ethash_return_value ethashReturn;
unsigned hashCount = 0; unsigned hashCount = 0;
for (; (std::chrono::steady_clock::now() - startTime) < std::chrono::milliseconds(_msTimeout) && _continue; tryNonce++, hashCount++) for (; (std::chrono::steady_clock::now() - startTime) < std::chrono::milliseconds(_msTimeout) && _continue; tryNonce++, hashCount++)
{ {
ethash_compute_full(&ethashReturn, d, &p, h.data(), tryNonce); u256 val(m.mine(tryNonce));
u256 val(h256(ethashReturn.result, h256::ConstructFromPointer));
best = std::min<double>(best, log2((double)val)); best = std::min<double>(best, log2((double)val));
if (val <= boundary) if (val <= boundary)
{ {
ret.first.completed = true; ret.first.completed = true;
result.mixHash = h256(ethashReturn.mix_hash, h256::ConstructFromPointer); result.mixHash = m.lastMixHash();
result.nonce = u64(tryNonce); result.nonce = u64(tryNonce);
break; break;
} }

10
libethcore/ProofOfWork.h

@ -49,20 +49,12 @@ struct MineInfo
class Ethash class Ethash
{ {
public: public:
// bit-compatible with ethash_return_value
struct Proof struct Proof
{ {
Nonce nonce; Nonce nonce;
h256 mixHash; h256 mixHash;
}; };
struct Result
{
h256 value;
h256 mixHash;
};
static Result eval(BlockInfo const& _header) { return eval(_header, _header.nonce); }
static Result eval(BlockInfo const& _header, Nonce const& _nonce);
static bool verify(BlockInfo const& _header); static bool verify(BlockInfo const& _header);
std::pair<MineInfo, Proof> mine(BlockInfo const& _header, unsigned _msTimeout = 100, bool _continue = true, bool _turbo = false); std::pair<MineInfo, Proof> mine(BlockInfo const& _header, unsigned _msTimeout = 100, bool _continue = true, bool _turbo = false);
static void assignResult(Proof const& _r, BlockInfo& _header) { _header.nonce = _r.nonce; _header.mixHash = _r.mixHash; } static void assignResult(Proof const& _r, BlockInfo& _header) { _header.nonce = _r.nonce; _header.mixHash = _r.mixHash; }
@ -78,9 +70,7 @@ public:
using Proof = Nonce; using Proof = Nonce;
static bool verify(BlockInfo const& _header) { return (bigint)(u256)Evaluator::eval(_header.headerHash(WithoutNonce), _header.nonce) <= (bigint(1) << 256) / _header.difficulty; } static bool verify(BlockInfo const& _header) { return (bigint)(u256)Evaluator::eval(_header.headerHash(WithoutNonce), _header.nonce) <= (bigint(1) << 256) / _header.difficulty; }
inline std::pair<MineInfo, Proof> mine(BlockInfo const& _header, unsigned _msTimeout = 100, bool _continue = true, bool _turbo = false); inline std::pair<MineInfo, Proof> mine(BlockInfo const& _header, unsigned _msTimeout = 100, bool _continue = true, bool _turbo = false);
static void assignResult(Proof const& _r, BlockInfo& _header) { _header.nonce = _r; } static void assignResult(Proof const& _r, BlockInfo& _header) { _header.nonce = _r; }
protected: protected:

6
libethereum/BlockChain.cpp

@ -308,7 +308,13 @@ h256s BlockChain::import(bytes const& _block, OverlayDB const& _db)
m_extrasDB->Put(m_writeOptions, toSlice(bi.parentHash), (ldb::Slice)dev::ref(m_details[bi.parentHash].rlp())); m_extrasDB->Put(m_writeOptions, toSlice(bi.parentHash), (ldb::Slice)dev::ref(m_details[bi.parentHash].rlp()));
m_extrasDB->Put(m_writeOptions, toSlice(newHash, 3), (ldb::Slice)dev::ref(m_logBlooms[newHash].rlp())); m_extrasDB->Put(m_writeOptions, toSlice(newHash, 3), (ldb::Slice)dev::ref(m_logBlooms[newHash].rlp()));
m_extrasDB->Put(m_writeOptions, toSlice(newHash, 4), (ldb::Slice)dev::ref(m_receipts[newHash].rlp())); m_extrasDB->Put(m_writeOptions, toSlice(newHash, 4), (ldb::Slice)dev::ref(m_receipts[newHash].rlp()));
m_extrasDB->Put(m_writeOptions, toSlice(newHash, 4), (ldb::Slice)dev::ref(m_receipts[newHash].rlp()));
m_db->Put(m_writeOptions, toSlice(newHash), (ldb::Slice)ref(_block)); m_db->Put(m_writeOptions, toSlice(newHash), (ldb::Slice)ref(_block));
RLP blockRLP(_block);
TransactionAddress ta;
ta.blockHash = newHash;
for (ta.index = 0; ta.index < blockRLP[1].itemCount(); ++ta.index)
m_extrasDB->Put(m_writeOptions, toSlice(sha3(blockRLP[1][ta.index].data()), 5), (ldb::Slice)dev::ref(ta.rlp()));
#if ETH_PARANOIA #if ETH_PARANOIA
checkConsistency(); checkConsistency();

14
libethereum/BlockChain.h

@ -34,6 +34,7 @@
#include <libdevcore/Guards.h> #include <libdevcore/Guards.h>
#include "BlockDetails.h" #include "BlockDetails.h"
#include "Account.h" #include "Account.h"
#include "Transaction.h"
#include "BlockQueue.h" #include "BlockQueue.h"
namespace ldb = leveldb; namespace ldb = leveldb;
@ -61,6 +62,8 @@ std::map<Address, Account> const& genesisState();
ldb::Slice toSlice(h256 _h, unsigned _sub = 0); ldb::Slice toSlice(h256 _h, unsigned _sub = 0);
using TransactionHashes = h256s;
/** /**
* @brief Implements the blockchain database. All data this gives is disk-backed. * @brief Implements the blockchain database. All data this gives is disk-backed.
* @threadsafe * @threadsafe
@ -108,12 +111,19 @@ public:
BlockReceipts receipts(h256 _hash) const { return queryExtras<BlockReceipts, 4>(_hash, m_receipts, x_receipts, NullBlockReceipts); } BlockReceipts receipts(h256 _hash) const { return queryExtras<BlockReceipts, 4>(_hash, m_receipts, x_receipts, NullBlockReceipts); }
BlockReceipts receipts() const { return receipts(currentHash()); } BlockReceipts receipts() const { return receipts(currentHash()); }
/// Get a list of transaction hashes for a given block. Thread-safe.
TransactionHashes transactionHashes(h256 _hash) const { auto b = block(_hash); RLP rlp(b); h256s ret; for (auto t: rlp[1]) ret.push_back(sha3(t.data())); return ret; }
TransactionHashes transactionHashes() const { return transactionHashes(currentHash()); }
/// Get a block (RLP format) for the given hash (or the most recent mined if none given). Thread-safe. /// Get a block (RLP format) for the given hash (or the most recent mined if none given). Thread-safe.
bytes block(h256 _hash) const; bytes block(h256 _hash) const;
bytes block() const { return block(currentHash()); } bytes block() const { return block(currentHash()); }
/// Get a transaction from its hash. Thread-safe.
bytes transaction(h256 _transactionHash) const { TransactionAddress ta = queryExtras<TransactionAddress, 5>(_transactionHash, m_transactionAddresses, x_transactionAddresses, NullTransactionAddress); if (!ta) return bytes(); return transaction(ta.blockHash, ta.index); }
/// Get a block's transaction (RLP format) for the given block hash (or the most recent mined if none given) & index. Thread-safe. /// Get a block's transaction (RLP format) for the given block hash (or the most recent mined if none given) & index. Thread-safe.
bytes transaction(h256 _hash, unsigned _i) const { bytes b = block(_hash); return RLP(b)[1][_i].data().toBytes(); } bytes transaction(h256 _blockHash, unsigned _i) const { bytes b = block(_blockHash); return RLP(b)[1][_i].data().toBytes(); }
bytes transaction(unsigned _i) const { return transaction(currentHash(), _i); } bytes transaction(unsigned _i) const { return transaction(currentHash(), _i); }
/// Get a number for the given hash (or the most recent mined if none given). Thread-safe. /// Get a number for the given hash (or the most recent mined if none given). Thread-safe.
@ -185,6 +195,8 @@ private:
mutable BlockLogBloomsHash m_logBlooms; mutable BlockLogBloomsHash m_logBlooms;
mutable boost::shared_mutex x_receipts; mutable boost::shared_mutex x_receipts;
mutable BlockReceiptsHash m_receipts; mutable BlockReceiptsHash m_receipts;
mutable boost::shared_mutex x_transactionAddresses;
mutable TransactionAddressHash m_transactionAddresses;
mutable boost::shared_mutex x_cache; mutable boost::shared_mutex x_cache;
mutable std::map<h256, bytes> m_cache; mutable std::map<h256, bytes> m_cache;

14
libethereum/BlockDetails.h

@ -70,13 +70,27 @@ struct BlockReceipts
TransactionReceipts receipts; TransactionReceipts receipts;
}; };
struct TransactionAddress
{
TransactionAddress() {}
TransactionAddress(RLP const& _rlp) { blockHash = _rlp[0].toHash<h256>(); index = _rlp[1].toInt<unsigned>(); }
bytes rlp() const { RLPStream s(2); s << blockHash << index; return s.out(); }
explicit operator bool() const { return !!blockHash; }
h256 blockHash;
unsigned index = 0;
};
using BlockDetailsHash = std::map<h256, BlockDetails>; using BlockDetailsHash = std::map<h256, BlockDetails>;
using BlockLogBloomsHash = std::map<h256, BlockLogBlooms>; using BlockLogBloomsHash = std::map<h256, BlockLogBlooms>;
using BlockReceiptsHash = std::map<h256, BlockReceipts>; using BlockReceiptsHash = std::map<h256, BlockReceipts>;
using TransactionAddressHash = std::map<h256, TransactionAddress>;
static const BlockDetails NullBlockDetails; static const BlockDetails NullBlockDetails;
static const BlockLogBlooms NullBlockLogBlooms; static const BlockLogBlooms NullBlockLogBlooms;
static const BlockReceipts NullBlockReceipts; static const BlockReceipts NullBlockReceipts;
static const TransactionAddress NullTransactionAddress;
} }
} }

76
test/dagger.cpp

@ -17,37 +17,69 @@
/** @file dagger.cpp /** @file dagger.cpp
* @author Gav Wood <i@gavwood.com> * @author Gav Wood <i@gavwood.com>
* @date 2014 * @date 2014
* ProofOfWork test functions. * Dashimoto test functions.
*/ */
#include <chrono> #include <fstream>
#include <libdevcore/Log.h> #include <random>
#include "JsonSpiritHeaders.h"
#include <libdevcore/CommonIO.h>
#include <libethcore/ProofOfWork.h> #include <libethcore/ProofOfWork.h>
#include <libethcore/Ethasher.h>
#include <boost/test/unit_test.hpp>
#include "TestHelper.h"
using namespace std; using namespace std;
using namespace std::chrono;
using namespace dev; using namespace dev;
using namespace dev::eth; using namespace dev::eth;
int daggerTest() namespace js = json_spirit;
using dev::operator <<;
BOOST_AUTO_TEST_SUITE(DashimotoTests)
BOOST_AUTO_TEST_CASE(basic_test)
{ {
#if 0 string testPath = test::getTestPath();
cnote << "Testing ProofOfWork...";
// Test dagger testPath += "/PoWTests";
{
auto s = steady_clock::now(); cnote << "Testing Secure Trie...";
cout << hex << ProofOfWork().eval((h256)(u256)1, (h256)(u256)0); js::mValue v;
cout << " " << dec << duration_cast<milliseconds>(steady_clock::now() - s).count() << " ms" << endl; string s = asString(contents(testPath + "/ethash_tests.json"));
cout << hex << ProofOfWork().eval((h256)(u256)1, (h256)(u256)1); BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of 'ethash_tests.json' is empty. Have you cloned the 'tests' repo branch develop?");
cout << " " << dec << duration_cast<milliseconds>(steady_clock::now() - s).count() << " ms" << endl; js::read_string(s, v);
} for (auto& i: v.get_obj())
{ {
auto s = steady_clock::now(); cnote << i.first;
cout << hex << ProofOfWork().eval((h256)(u256)1, (h256)(u256)0); js::mObject& o = i.second.get_obj();
cout << " " << dec << duration_cast<milliseconds>(steady_clock::now() - s).count() << " ms" << endl; vector<pair<string, string>> ss;
cout << hex << ProofOfWork().eval((h256)(u256)1, (h256)(u256)1); BlockInfo header = BlockInfo::fromHeader(fromHex(o["header"].get_str()));
cout << " " << dec << duration_cast<milliseconds>(steady_clock::now() - s).count() << " ms" << endl; h256 headerHash(o["header_hash"].get_str());
} Nonce nonce(o["nonce"].get_str());
BOOST_REQUIRE_EQUAL(headerHash, header.headerHash(WithoutNonce));
BOOST_REQUIRE_EQUAL(nonce, header.nonce);
unsigned cacheSize(o["cache_size"].get_int());
h256 cacheHash(o["cache_hash"].get_str());
BOOST_REQUIRE_EQUAL(Ethasher::get()->cache(header).size(), cacheSize);
BOOST_REQUIRE_EQUAL(sha3(Ethasher::get()->cache(header)), cacheHash);
#if TEST_FULL
unsigned fullSize(o["full_size"].get_int());
h256 fullHash(o["full_hash"].get_str());
BOOST_REQUIRE_EQUAL(Ethasher::get()->full(header).size(), fullSize);
BOOST_REQUIRE_EQUAL(sha3(Ethasher::get()->full(header)), fullHash);
#endif #endif
return 0;
h256 result(o["result"].get_str());
Ethasher::Result r = Ethasher::eval(header);
BOOST_REQUIRE_EQUAL(r.value, result);
BOOST_REQUIRE_EQUAL(r.mixHash, header.mixHash);
}
} }
BOOST_AUTO_TEST_SUITE_END()

Loading…
Cancel
Save