Browse Source

Merge remote-tracking branch 'up/develop' into deploydialog

cl-refactor
yann300 10 years ago
parent
commit
1dbe8ebb6a
  1. 2
      CMakeLists.txt
  2. 8
      alethzero/Context.h
  3. 16
      alethzero/MainWin.cpp
  4. 2
      alethzero/Transact.cpp
  5. 2
      libdevcrypto/CMakeLists.txt
  6. 2
      libethcore/EthashCPUMiner.cpp
  7. 1
      libethcore/EthashGPUMiner.cpp
  8. 37
      libethereum/BlockChain.cpp
  9. 14
      libethereum/BlockChain.h
  10. 2
      libethereum/BlockDetails.h
  11. 2
      libethereum/BlockQueue.cpp
  12. 2
      libethereum/BlockQueue.h
  13. 56
      libethereum/DownloadMan.cpp
  14. 104
      libethereum/DownloadMan.h
  15. 1
      libethereum/TransactionQueue.cpp
  16. 11
      libwhisper/Message.h
  17. 21
      libwhisper/WhisperDB.cpp
  18. 3
      libwhisper/WhisperDB.h
  19. 41
      libwhisper/WhisperHost.cpp
  20. 1
      libwhisper/WhisperHost.h
  21. 2
      test/CMakeLists.txt
  22. 9
      test/libp2p/peer.cpp
  23. 2
      test/libwhisper/whisperDB.cpp

2
CMakeLists.txt

@ -405,10 +405,8 @@ if (JSCONSOLE)
add_subdirectory(ethconsole)
endif ()
if (NOT WIN32)
add_definitions(-DETH_HAVE_SECP256K1)
add_subdirectory(secp256k1)
endif ()
add_subdirectory(libscrypt)
add_subdirectory(libdevcrypto)

8
alethzero/Context.h

@ -32,10 +32,10 @@ class QSpinBox;
namespace dev { namespace eth { struct StateDiff; class KeyManager; } }
#define Small "font-size: small; "
#define Mono "font-family: Ubuntu Mono, Monospace, Lucida Console, Courier New; font-weight: bold; "
#define Div(S) "<div style=\"" S "\">"
#define Span(S) "<span style=\"" S "\">"
#define ETH_HTML_SMALL "font-size: small; "
#define ETH_HTML_MONO "font-family: Ubuntu Mono, Monospace, Lucida Console, Courier New; font-weight: bold; "
#define ETH_HTML_DIV(S) "<div style=\"" S "\">"
#define ETH_HTML_SPAN(S) "<span style=\"" S "\">"
void initUnits(QComboBox* _b);
void setValueUnits(QComboBox* _units, QSpinBox* _value, dev::u256 _v);

16
alethzero/MainWin.cpp

@ -594,7 +594,7 @@ void Main::eval(QString const& _js)
void Main::addConsoleMessage(QString const& _js, QString const& _s)
{
m_consoleHistory.push_back(qMakePair(_js, _s));
QString r = "<html><body style=\"margin: 0;\">" Div(Mono "position: absolute; bottom: 0; border: 0px; margin: 0px; width: 100%");
QString r = "<html><body style=\"margin: 0;\">" ETH_HTML_DIV(ETH_HTML_MONO "position: absolute; bottom: 0; border: 0px; margin: 0px; width: 100%");
for (auto const& i: m_consoleHistory)
r += "<div style=\"border-bottom: 1 solid #eee; width: 100%\"><span style=\"float: left; width: 1em; color: #888; font-weight: bold\">&gt;</span><span style=\"color: #35d\">" + i.first.toHtmlEscaped() + "</span></div>"
"<div style=\"border-bottom: 1 solid #eee; width: 100%\"><span style=\"float: left; width: 1em\">&nbsp;</span><span>" + i.second + "</span></div>";
@ -1623,7 +1623,7 @@ void Main::on_transactionQueue_currentItemChanged()
if (tx.data().size())
s << dev::memDump(tx.data(), 16, true);
}
s << "<div>Hex: " Span(Mono) << toHex(tx.rlp()) << "</span></div>";
s << "<div>Hex: " ETH_HTML_SPAN(ETH_HTML_MONO) << toHex(tx.rlp()) << "</span></div>";
s << "<hr/>";
if (!!receipt.bloom())
s << "<div>Log Bloom: " << receipt.bloom() << "</div>";
@ -1633,7 +1633,7 @@ void Main::on_transactionQueue_currentItemChanged()
s << "<div>End State: <b>" << receipt.stateRoot().abridged() << "</b></div>";
auto r = receipt.rlp();
s << "<div>Receipt: " << toString(RLP(r)) << "</div>";
s << "<div>Receipt-Hex: " Span(Mono) << toHex(receipt.rlp()) << "</span></div>";
s << "<div>Receipt-Hex: " ETH_HTML_SPAN(ETH_HTML_MONO) << toHex(receipt.rlp()) << "</span></div>";
s << renderDiff(ethereum()->diff(i, PendingBlock));
// s << "Pre: " << fs.rootHash() << "<br/>";
// s << "Post: <b>" << ts.rootHash() << "</b>";
@ -1769,8 +1769,8 @@ void Main::on_blocks_currentItemChanged()
++ii;
}
s << "<div>Post: <b>" << info.stateRoot() << "</b>" << "</div>";
s << "<div>Dump: " Span(Mono) << toHex(block[0].data()) << "</span>" << "</div>";
s << "<div>Receipts-Hex: " Span(Mono) << toHex(receipts.rlp()) << "</span></div>";
s << "<div>Dump: " ETH_HTML_SPAN(ETH_HTML_MONO) << toHex(block[0].data()) << "</span>" << "</div>";
s << "<div>Receipts-Hex: " ETH_HTML_SPAN(ETH_HTML_MONO) << toHex(receipts.rlp()) << "</span></div>";
}
else
{
@ -1801,7 +1801,7 @@ void Main::on_blocks_currentItemChanged()
else
s << "<h4>Data</h4>" << dev::memDump(tx.data(), 16, true);
}
s << "<div>Hex: " Span(Mono) << toHex(block[1][txi].data()) << "</span></div>";
s << "<div>Hex: " ETH_HTML_SPAN(ETH_HTML_MONO) << toHex(block[1][txi].data()) << "</span></div>";
s << "<hr/>";
if (!!receipt.bloom())
s << "<div>Log Bloom: " << receipt.bloom() << "</div>";
@ -1811,7 +1811,7 @@ void Main::on_blocks_currentItemChanged()
s << "<div>End State: <b>" << receipt.stateRoot().abridged() << "</b></div>";
auto r = receipt.rlp();
s << "<div>Receipt: " << toString(RLP(r)) << "</div>";
s << "<div>Receipt-Hex: " Span(Mono) << toHex(receipt.rlp()) << "</span></div>";
s << "<div>Receipt-Hex: " ETH_HTML_SPAN(ETH_HTML_MONO) << toHex(receipt.rlp()) << "</span></div>";
s << "<h4>Diff</h4>" << renderDiff(ethereum()->diff(txi, h));
ui->debugCurrent->setEnabled(true);
ui->debugDumpState->setEnabled(true);
@ -1881,7 +1881,7 @@ void Main::on_accounts_currentItemChanged()
for (auto const& i: storage)
s << "@" << showbase << hex << prettyU256(i.first) << "&nbsp;&nbsp;&nbsp;&nbsp;" << showbase << hex << prettyU256(i.second) << "<br/>";
s << "<h4>Body Code (" << sha3(ethereum()->codeAt(address)).abridged() << ")</h4>" << disassemble(ethereum()->codeAt(address));
s << Div(Mono) << toHex(ethereum()->codeAt(address)) << "</div>";
s << ETH_HTML_DIV(ETH_HTML_MONO) << toHex(ethereum()->codeAt(address)) << "</div>";
ui->accountInfo->appendHtml(QString::fromStdString(s.str()));
}
catch (dev::InvalidTrie)

2
alethzero/Transact.cpp

@ -346,7 +346,7 @@ void Transact::rejigData()
htmlInfo = "<h4>Dump</h4>" + QString::fromStdString(dev::memDump(m_data, 8, true));
}
htmlInfo += "<h4>Hex</h4>" + QString(Div(Mono)) + QString::fromStdString(toHex(m_data)) + "</div>";
htmlInfo += "<h4>Hex</h4>" + QString(ETH_HTML_DIV(ETH_HTML_MONO)) + QString::fromStdString(toHex(m_data)) + "</div>";
// Determine the minimum amount of gas we need to play...
qint64 baseGas = (qint64)Transaction::gasRequired(m_data, 0);

2
libdevcrypto/CMakeLists.txt

@ -24,10 +24,8 @@ target_link_libraries(${EXECUTABLE} ${DB_LIBRARIES})
target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES})
target_link_libraries(${EXECUTABLE} scrypt)
target_link_libraries(${EXECUTABLE} devcore)
if (NOT WIN32)
add_definitions(-DETH_HAVE_SECP256K1)
target_link_libraries(${EXECUTABLE} secp256k1)
endif ()
install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib )
install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} )

2
libethcore/EthashCPUMiner.cpp

@ -35,6 +35,7 @@ using namespace eth;
unsigned EthashCPUMiner::s_numInstances = 0;
#if ETH_CPUID || !ETH_TRUE
static string jsonEncode(map<string, string> const& _m)
{
string ret = "{";
@ -50,6 +51,7 @@ static string jsonEncode(map<string, string> const& _m)
return ret + "}";
}
#endif
void EthashCPUMiner::workLoop()
{

1
libethcore/EthashGPUMiner.cpp

@ -26,7 +26,6 @@
#include "EthashGPUMiner.h"
#include <thread>
#include <chrono>
#include <cpuid.h>
#include <libethash-cl/ethash_cl_miner.h>
using namespace std;
using namespace dev;

37
libethereum/BlockChain.cpp

@ -85,15 +85,34 @@ std::ostream& dev::eth::operator<<(std::ostream& _out, BlockChain const& _bc)
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);
static thread_local FixedHash<33> h = _h;
h[32] = (uint8_t)_sub;
return (ldb::Slice)h.ref();
#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);
return (ldb::Slice)t_h->ref();
#endif //ALL_COMPILERS_ARE_CPP11_COMPLIANT
}
ldb::Slice dev::eth::toSlice(uint64_t _n, unsigned _sub)
{
#if ALL_COMPILERS_ARE_CPP11_COMPLIANT
static thread_local FixedHash<33> h;
toBigEndian(_n, bytesRef(h.data() + 24, 8));
h[32] = (uint8_t)_sub;
return (ldb::Slice)h.ref();
#else
static boost::thread_specific_ptr<FixedHash<33>> t_h;
if (!t_h.get())
t_h.reset(new FixedHash<33>);
bytesRef ref(t_h->data() + 24, 8);
toBigEndian(_n, ref);
(*t_h)[32] = (uint8_t)_sub;
return (ldb::Slice)t_h->ref();
#endif
}
@ -289,7 +308,7 @@ void BlockChain::rebuild(std::string const& _path, std::function<void(unsigned,
}
try
{
bytes b = block(queryExtras<BlockHash, ExtraBlockHash>(h256(u256(d)), m_blockHashes, x_blockHashes, NullBlockHash, oldExtrasDB).value);
bytes b = block(queryExtras<BlockHash, uint64_t, ExtraBlockHash>(d, m_blockHashes, x_blockHashes, NullBlockHash, oldExtrasDB).value);
BlockInfo bi(&b);
if (_prepPoW)
@ -359,7 +378,8 @@ tuple<ImportRoute, bool, unsigned> BlockChain::sync(BlockQueue& _bq, OverlayDB c
r = import(block.verified, _stateDB, ImportRequirements::Everything & ~ImportRequirements::ValidSeal & ~ImportRequirements::CheckUncles);
fresh += r.liveBlocks;
dead += r.deadBlocks;
goodTransactions += r.goodTranactions;
goodTransactions.reserve(goodTransactions.size() + r.goodTranactions.size());
std::move(std::begin(r.goodTranactions), std::end(r.goodTranactions), std::back_inserter(goodTransactions));
++count;
}
catch (dev::eth::UnknownParent)
@ -607,7 +627,7 @@ ImportRoute BlockChain::import(VerifiedBlockRef const& _block, OverlayDB const&
unsigned n = number(route.front());
DEV_WRITE_GUARDED(x_blockHashes)
for (auto i = route.begin(); i != route.end() && *i != common; ++i, --n)
m_blockHashes.erase(h256(u256(n)));
m_blockHashes.erase(n);
DEV_WRITE_GUARDED(x_transactionAddresses)
m_transactionAddresses.clear(); // TODO: could perhaps delete them individually?
@ -947,7 +967,7 @@ void BlockChain::noteUsed(h256 const& _h, unsigned _extra) const
m_inUse.insert(id);
}
template <class T> static unsigned getHashSize(unordered_map<h256, T> const& _map)
template <class K, class T> static unsigned getHashSize(unordered_map<K, T> const& _map)
{
unsigned ret = 0;
for (auto const& i: _map)
@ -1005,9 +1025,6 @@ void BlockChain::garbageCollect(bool _force)
case ExtraDetails:
m_details.erase(id.first);
break;
case ExtraBlockHash:
m_blockHashes.erase(id.first);
break;
case ExtraReceipts:
m_receipts.erase(id.first);
break;

14
libethereum/BlockChain.h

@ -72,6 +72,7 @@ struct BlockChainDebug: public LogChannel { static const char* name(); static co
std::unordered_map<Address, Account> const& genesisState();
ldb::Slice toSlice(h256 const& _h, unsigned _sub = 0);
ldb::Slice toSlice(uint64_t _n, unsigned _sub = 0);
using BlocksHash = std::unordered_map<h256, bytes>;
using TransactionHashes = h256s;
@ -168,7 +169,7 @@ public:
UncleHashes uncleHashes() const { return uncleHashes(currentHash()); }
/// Get the hash for a given block's number.
h256 numberHash(unsigned _i) const { if (!_i) return genesisHash(); return queryExtras<BlockHash, ExtraBlockHash>(h256(_i), m_blockHashes, x_blockHashes, NullBlockHash).value; }
h256 numberHash(unsigned _i) const { if (!_i) return genesisHash(); return queryExtras<BlockHash, uint64_t, ExtraBlockHash>(_i, m_blockHashes, x_blockHashes, NullBlockHash).value; }
/// Get the last N hashes for a given block. (N is determined by the LastHashes type.)
LastHashes lastHashes() const { return lastHashes(number()); }
@ -293,7 +294,7 @@ protected:
unsigned open(std::string const& _path, WithExisting _we = WithExisting::Trust);
void close();
template<class T, unsigned N> T queryExtras(h256 const& _h, std::unordered_map<h256, T>& _m, boost::shared_mutex& _x, T const& _n, ldb::DB* _extrasDB = nullptr) const
template<class T, class K, unsigned N> T queryExtras(K const& _h, std::unordered_map<K, T>& _m, boost::shared_mutex& _x, T const& _n, ldb::DB* _extrasDB = nullptr) const
{
{
ReadGuard l(_x);
@ -305,10 +306,7 @@ protected:
std::string s;
(_extrasDB ? _extrasDB : m_extrasDB)->Get(m_readOptions, toSlice(_h, N), &s);
if (s.empty())
{
// cout << "Not found in DB: " << _h << endl;
return _n;
}
noteUsed(_h, N);
@ -317,6 +315,11 @@ protected:
return ret.first->second;
}
template<class T, unsigned N> T queryExtras(h256 const& _h, std::unordered_map<h256, T>& _m, boost::shared_mutex& _x, T const& _n, ldb::DB* _extrasDB = nullptr) const
{
return queryExtras<T, h256, N>(_h, _m, _x, _n, _extrasDB);
}
void checkConsistency();
/// The caches of the disk DB and their locks.
@ -340,6 +343,7 @@ protected:
mutable std::deque<std::unordered_set<CacheID>> m_cacheUsage;
mutable std::unordered_set<CacheID> m_inUse;
void noteUsed(h256 const& _h, unsigned _extra = (unsigned)-1) const;
void noteUsed(uint64_t const& _h, unsigned _extra = (unsigned)-1) const { (void)_h; (void)_extra; } // don't note non-hash types
std::chrono::system_clock::time_point m_lastCollection;
void noteCanonChanged() const { Guard l(x_lastLastHashes); m_lastLastHashes.clear(); }

2
libethereum/BlockDetails.h

@ -114,7 +114,7 @@ using BlockDetailsHash = std::unordered_map<h256, BlockDetails>;
using BlockLogBloomsHash = std::unordered_map<h256, BlockLogBlooms>;
using BlockReceiptsHash = std::unordered_map<h256, BlockReceipts>;
using TransactionAddressHash = std::unordered_map<h256, TransactionAddress>;
using BlockHashHash = std::unordered_map<h256, BlockHash>;
using BlockHashHash = std::unordered_map<uint64_t, BlockHash>;
using BlocksBloomsHash = std::unordered_map<h256, BlocksBlooms>;
static const BlockDetails NullBlockDetails;

2
libethereum/BlockQueue.cpp

@ -292,7 +292,7 @@ void BlockQueue::updateBad_WITH_LOCK(h256 const& _bad)
while (moreBad)
{
moreBad = false;
std::vector<VerifiedBlock> oldVerified;
std::deque<VerifiedBlock> oldVerified;
swap(m_verified, oldVerified);
for (auto& b: oldVerified)
if (m_knownBad.count(b.verified.info.parentHash()) || m_knownBad.count(b.verified.info.hash()))

2
libethereum/BlockQueue.h

@ -154,7 +154,7 @@ private:
mutable Mutex m_verification; ///< Mutex that allows writing to m_verified, m_verifying and m_unverified.
std::condition_variable m_moreToVerify; ///< Signaled when m_unverified has a new entry.
std::vector<VerifiedBlock> m_verified; ///< List of blocks, in correct order, verified and ready for chain-import.
std::deque<VerifiedBlock> m_verified; ///< List of blocks, in correct order, verified and ready for chain-import.
std::deque<VerifiedBlock> m_verifying; ///< List of blocks being verified; as long as the block component (bytes) is empty, it's not finished.
std::deque<UnverifiedBlock> m_unverified; ///< List of <block hash, parent hash, block data> in correct order, ready for verification.

56
libethereum/DownloadMan.cpp

@ -24,6 +24,8 @@ using namespace std;
using namespace dev;
using namespace dev::eth;
size_t const c_maxDownloadAhead = 50000; // Must not be higher than BlockQueue::c_maxUnknownCount
DownloadMan::Overview DownloadMan::overview() const
{
ReadGuard l(m_lock);
@ -63,9 +65,10 @@ h256Hash DownloadSub::nextFetch(unsigned _n)
if (!m_man || m_man->chainEmpty())
return h256Hash();
m_asked = (~(m_man->taken() + m_attempted)).lowest(_n);
if (m_asked.empty())
m_asked = (~(m_man->taken(true) + m_attempted)).lowest(_n);
RangeMask<unsigned> downloaded = m_man->taken(true);
m_asked = (~(m_man->taken(false) + m_attempted)).lowest(_n);
if (m_asked.empty() || m_asked.lastIn() - downloaded.firstOut() >= c_maxDownloadAhead)
m_asked = (~(downloaded + m_attempted)).lowest(_n);
m_attempted += m_asked;
for (auto i: m_asked)
{
@ -85,50 +88,3 @@ bool DownloadSub::noteBlock(h256 _hash)
m_remaining.erase(_hash);
return ret;
}
HashDownloadSub::HashDownloadSub(HashDownloadMan& _man): m_man(&_man)
{
WriteGuard l(m_man->x_subs);
m_asked = RangeMask<unsigned>(m_man->m_chainStart, m_man->m_chainStart + m_man->m_chainCount);
m_man->m_subs.insert(this);
}
HashDownloadSub::~HashDownloadSub()
{
if (m_man)
{
WriteGuard l(m_man->x_subs);
m_man->m_subs.erase(this);
}
}
void HashDownloadSub::resetFetch()
{
Guard l(m_fetch);
m_remaining = 0;
m_asked = RangeMask<unsigned>(m_man->m_chainStart, m_man->m_chainStart + m_man->m_chainCount);
}
unsigned HashDownloadSub::nextFetch(unsigned _n)
{
Guard l(m_fetch);
m_asked = RangeMask<unsigned>(m_man->m_chainStart, m_man->m_chainStart + m_man->m_chainCount);
if (!m_man || m_man->chainEmpty())
return 0;
m_asked = (~(m_man->taken())).lowest(_n);
if (m_asked.empty())
m_asked = (~(m_man->taken(true))).lowest(_n);
return *m_asked.begin();
}
void HashDownloadSub::noteHash(unsigned _index, unsigned _size)
{
Guard l(m_fetch);
if (m_man)
for(unsigned i = _index; i < _index + _size; ++i)
if (i >= m_man->m_got.all().first && i < m_man->m_got.all().second)
m_man->m_got += i;
}

104
libethereum/DownloadMan.h

@ -170,110 +170,6 @@ private:
std::unordered_set<DownloadSub*> m_subs;
};
class HashDownloadMan;
class HashDownloadSub
{
friend class HashDownloadMan;
public:
HashDownloadSub(HashDownloadMan& _man);
~HashDownloadSub();
/// Finished last fetch - grab the next hash index to download
unsigned nextFetch(unsigned _n);
/// Note that we've received a particular hash range.
void noteHash(unsigned _index, unsigned count);
/// Nothing doing here.
void doneFetch() { resetFetch(); }
bool askedContains(unsigned _i) const { Guard l(m_fetch); return m_asked.contains(_i); }
RangeMask<unsigned> const& asked() const { return m_asked; }
private:
void resetFetch(); // Called by DownloadMan when we need to reset the download.
HashDownloadMan* m_man = nullptr;
mutable Mutex m_fetch;
unsigned m_remaining;
RangeMask<unsigned> m_asked;
};
class HashDownloadMan
{
friend class HashDownloadSub;
public:
~HashDownloadMan()
{
for (auto i: m_subs)
i->m_man = nullptr;
}
void resetToRange(unsigned _start, unsigned _count)
{
{
ReadGuard l(x_subs);
for (auto i: m_subs)
i->resetFetch();
}
WriteGuard l(m_lock);
m_chainStart = _start;
m_chainCount = _count;
m_got += RangeMask<unsigned>(_start, _start + _count);
{
ReadGuard l(x_subs);
for (auto i: m_subs)
i->resetFetch();
}
}
void reset(unsigned _start)
{
WriteGuard l(m_lock);
m_chainStart = _start;
m_chainCount = 0;
m_got = RangeMask<unsigned>(_start, _start);
}
RangeMask<unsigned> taken(bool _desperate = false) const
{
ReadGuard l(m_lock);
auto ret = m_got;
if (!_desperate)
{
ReadGuard l(x_subs);
for (auto i: m_subs)
ret += i->m_asked;
}
return ret;
}
bool isComplete() const
{
ReadGuard l(m_lock);
return m_got.full();
}
size_t chainSize() const { ReadGuard l(m_lock); return m_chainCount; }
size_t chainEmpty() const { ReadGuard l(m_lock); return m_chainCount == 0; }
void foreachSub(std::function<void(HashDownloadSub const&)> const& _f) const { ReadGuard l(x_subs); for(auto i: m_subs) _f(*i); }
unsigned subCount() const { ReadGuard l(x_subs); return m_subs.size(); }
RangeMask<unsigned> hashesGot() const { ReadGuard l(m_lock); return m_got; }
private:
mutable SharedMutex m_lock;
unsigned m_chainStart = 0;
unsigned m_chainCount = 0;
RangeMask<unsigned> m_got;
mutable SharedMutex x_subs;
std::unordered_set<HashDownloadSub*> m_subs;
};
}
}

1
libethereum/TransactionQueue.cpp

@ -107,6 +107,7 @@ ImportResult TransactionQueue::import(Transaction const& _transaction, IfDropped
return ir;
{
_transaction.safeSender(); // Perform EC recovery outside of the write lock
UpgradeGuard ul(l);
ret = manageImport_WITH_LOCK(h, _transaction);
}

11
libwhisper/Message.h

@ -64,10 +64,11 @@ public:
Envelope() {}
Envelope(RLP const& _m);
operator bool() const { return !!m_expiry; }
void streamRLP(RLPStream& _s, IncludeNonce _withNonce = WithNonce) const { _s.appendList(_withNonce ? 5 : 4) << m_expiry << m_ttl << m_topic << m_data; if (_withNonce) _s << m_nonce; }
h256 sha3(IncludeNonce _withNonce = WithNonce) const { RLPStream s; streamRLP(s, _withNonce); return dev::sha3(s.out()); }
Message open(Topics const& _t, Secret const& _s = Secret()) const;
unsigned workProved() const;
void proveWork(unsigned _ms);
unsigned sent() const { return m_expiry - m_ttl; }
unsigned expiry() const { return m_expiry; }
@ -75,12 +76,8 @@ public:
AbridgedTopics const& topic() const { return m_topic; }
bytes const& data() const { return m_data; }
Message open(Topics const& _t, Secret const& _s = Secret()) const;
unsigned workProved() const;
void proveWork(unsigned _ms);
bool matchesBloomFilter(TopicBloomFilterHash const& f) const;
bool isExpired() const { return m_expiry <= (unsigned)time(0); }
private:
Envelope(unsigned _exp, unsigned _ttl, AbridgedTopics const& _topic): m_expiry(_exp), m_ttl(_ttl), m_topic(_topic) {}

21
libwhisper/WhisperDB.cpp

@ -85,8 +85,8 @@ void WhisperDB::loadAll(std::map<h256, Envelope>& o_dst)
op.fill_cache = false;
op.verify_checksums = true;
vector<string> wasted;
unsigned now = (unsigned)time(0);
unique_ptr<leveldb::Iterator> it(m_db->NewIterator(op));
unsigned const now = (unsigned)time(0);
for (it->SeekToFirst(); it->Valid(); it->Next())
{
@ -135,3 +135,22 @@ void WhisperDB::loadAll(std::map<h256, Envelope>& o_dst)
}
}
void WhisperDB::save(h256 const& _key, Envelope const& _e)
{
try
{
RLPStream rlp;
_e.streamRLP(rlp);
bytes b;
rlp.swapOut(b);
insert(_key, b);
}
catch(RLPException const& ex)
{
cwarn << boost::diagnostic_information(ex);
}
catch(FailedInsertInLevelDB const& ex)
{
cwarn << boost::diagnostic_information(ex);
}
}

3
libwhisper/WhisperDB.h

@ -47,11 +47,14 @@ class WhisperDB
void insert(dev::h256 const& _key, bytes const& _value);
void kill(dev::h256 const& _key);
void loadAll(std::map<h256, Envelope>& o_dst);
void save(dev::h256 const& _key, Envelope const& _e);
private:
leveldb::ReadOptions m_readOptions;
leveldb::WriteOptions m_writeOptions;
std::unique_ptr<leveldb::DB> m_db;
enum MetaInformation { StoreForeverFlag = 1, WatchedFlag = 2 };
};
}

41
libwhisper/WhisperHost.cpp

@ -59,7 +59,7 @@ void WhisperHost::inject(Envelope const& _m, WhisperPeer* _p)
cnote << this << ": inject: " << _m.expiry() << _m.ttl() << _m.topic() << toHex(_m.data());
if (_m.expiry() <= (unsigned)time(0))
if (_m.isExpired())
return;
auto h = _m.sha3();
@ -84,7 +84,7 @@ void WhisperHost::inject(Envelope const& _m, WhisperPeer* _p)
for (auto const& f: m_filters)
if (f.second.filter.matches(_m))
for (auto& i: m_watches)
if (i.second.id == f.first)
if (i.second.id == f.first) // match one of the watches
{
i.second.changes.push_back(h);
rating += 2;
@ -204,6 +204,18 @@ void WhisperHost::noteAdvertiseTopicsOfInterest()
i.first->cap<WhisperPeer>().get()->noteAdvertiseTopicsOfInterest();
}
bool WhisperHost::isWatched(Envelope const& _e) const
{
DEV_GUARDED(m_filterLock)
if (_e.matchesBloomFilter(m_bloom))
for (auto const& f: m_filters)
if (f.second.filter.matches(_e))
for (auto const& i: m_watches)
if (i.second.id == f.first)
return true;
return false;
}
void WhisperHost::saveMessagesToBD()
{
if (!m_useDB)
@ -213,31 +225,16 @@ void WhisperHost::saveMessagesToBD()
{
WhisperDB db;
ReadGuard g(x_messages);
unsigned now = (unsigned)time(0);
for (auto const& m: m_messages)
{
RLPStream rlp;
m.second.streamRLP(rlp);
bytes b;
rlp.swapOut(b);
db.insert(m.first, b);
}
if (m.second.expiry() > now)
if (isWatched(m.second))
db.save(m.first, m.second);
}
catch(FailedToOpenLevelDB const& ex)
{
cwarn << "Exception in WhisperHost::saveMessagesToBD() - failed to open DB:" << ex.what();
}
catch(FailedInsertInLevelDB const& ex)
{
cwarn << "Exception in WhisperHost::saveMessagesToBD() - failed to insert:" << ex.what();
}
catch(FailedLookupInLevelDB const& ex)
{
cwarn << "Exception in WhisperHost::saveMessagesToBD() - failed lookup:" << ex.what();
}
catch(FailedDeleteInLevelDB const& ex)
{
cwarn << "Exception in WhisperHost::saveMessagesToBD() - failed to delete:" << ex.what();
}
catch(Exception const& ex)
{
cwarn << "Exception in WhisperHost::saveMessagesToBD():" << ex.what();
@ -260,6 +257,8 @@ void WhisperHost::loadMessagesFromBD()
db.loadAll(m);
WriteGuard g(x_messages);
m_messages.swap(m);
for (auto const& msg: m)
m_expiryQueue.insert(make_pair(msg.second.expiry(), msg.first));
}
catch(Exception const& ex)
{

1
libwhisper/WhisperHost.h

@ -67,6 +67,7 @@ public:
protected:
virtual void doWork() override;
void noteAdvertiseTopicsOfInterest();
bool isWatched(Envelope const& _e) const;
private:
virtual void onStarting() override { startWorking(); }

2
test/CMakeLists.txt

@ -75,9 +75,7 @@ target_link_libraries(testeth ${CURL_LIBRARIES})
target_link_libraries(testeth ${CRYPTOPP_LIBRARIES})
target_link_libraries(testeth ethereum)
target_link_libraries(testeth ethcore)
if (NOT WIN32)
target_link_libraries(testeth secp256k1)
endif()
if (JSCONSOLE)
target_link_libraries(testeth jsengine)

9
test/libp2p/peer.cpp

@ -44,8 +44,8 @@ BOOST_AUTO_TEST_CASE(host)
return;
VerbosityHolder setTemporaryLevel(10);
NetworkPreferences host1prefs("127.0.0.1", 30301, false);
NetworkPreferences host2prefs("127.0.0.1", 30302, false);
NetworkPreferences host1prefs("127.0.0.1", 30311, false);
NetworkPreferences host2prefs("127.0.0.1", 30312, false);
Host host1("Test", host1prefs);
Host host2("Test", host2prefs);
host1.start();
@ -67,9 +67,8 @@ BOOST_AUTO_TEST_CASE(host)
for (int i = 0; i < 3000 && (!host1.peerCount() || !host2.peerCount()); i += step)
this_thread::sleep_for(chrono::milliseconds(step));
//Temporary disabled
//BOOST_REQUIRE_EQUAL(host1.peerCount(), 1);
//BOOST_REQUIRE_EQUAL(host2.peerCount(), 1);
BOOST_REQUIRE_EQUAL(host1.peerCount(), 1);
BOOST_REQUIRE_EQUAL(host2.peerCount(), 1);
}
BOOST_AUTO_TEST_CASE(networkConfig)

2
test/libwhisper/whisperDB.cpp

@ -141,6 +141,7 @@ BOOST_AUTO_TEST_CASE(messages)
auto wh = h.registerCapability(new WhisperHost(true));
preexisting = wh->all();
cnote << preexisting.size() << "preexisting messages in DB";
wh->installWatch(BuildTopic("test"));
for (unsigned i = 0; i < TestSize; ++i)
wh->post(us.sec(), RLPStream().append(i).out(), BuildTopic("test"), 0xFFFFF);
@ -152,6 +153,7 @@ BOOST_AUTO_TEST_CASE(messages)
p2p::Host h("Test");
auto wh = h.registerCapability(new WhisperHost(true));
map<h256, Envelope> m2 = wh->all();
wh->installWatch(BuildTopic("test"));
BOOST_REQUIRE_EQUAL(m1.size(), m2.size());
BOOST_REQUIRE_EQUAL(m1.size() - preexisting.size(), TestSize);

Loading…
Cancel
Save