Browse Source

Merge branch 'develop' into crypto

Conflicts:
	libdevcrypto/Common.cpp
	libdevcrypto/EC.cpp
cl-refactor
subtly 10 years ago
parent
commit
737e6163cc
  1. 8
      alethzero/MainWin.cpp
  2. 2
      alethzero/MainWin.h
  3. 96
      exp/main.cpp
  4. 2
      libdevcore/Common.cpp
  5. 2
      libdevcore/CommonIO.cpp
  6. 3
      libdevcore/RLP.h
  7. 3
      libdevcrypto/Common.cpp
  8. 2
      libethcore/CommonEth.cpp
  9. 7
      libethereum/Executive.cpp
  10. 22
      libethereum/State.cpp
  11. 2
      libethereum/TransactionReceipt.h
  12. 26
      libevm/VM.h
  13. 12
      libevmcore/Instruction.cpp
  14. 2
      libwhisper/Common.h
  15. 2
      libwhisper/Message.h
  16. 9
      test/createRandomTest.cpp
  17. 16
      test/vm.cpp
  18. 84
      test/whisperTopic.cpp

8
alethzero/MainWin.cpp

@ -1258,9 +1258,10 @@ void Main::on_blocks_currentItemChanged()
s << "<br/>Coinbase: <b>" << pretty(info.coinbaseAddress).toHtmlEscaped().toStdString() << "</b> " << info.coinbaseAddress;
s << "<br/>Nonce: <b>" << info.nonce << "</b>";
s << "<br/>Parent: <b>" << info.parentHash << "</b>";
s << "<br/>Bloom: <b>" << details.bloom << "</b>";
// s << "<br/>Bloom: <b>" << details.bloom << "</b>";
s << "<br/>Log Bloom: <b>" << info.logBloom << "</b>";
s << "<br/>Transactions: <b>" << block[1].itemCount() << "</b> @<b>" << info.transactionsRoot << "</b>";
s << "<br/>Receipts: @<b>" << info.receiptsRoot << "</b>:";
s << "<br/>Uncles: <b>" << block[2].itemCount() << "</b> @<b>" << info.sha3Uncles << "</b>";
for (auto u: block[2])
{
@ -1283,6 +1284,7 @@ void Main::on_blocks_currentItemChanged()
Transaction tx(block[1][txi].data());
auto ss = tx.safeSender();
h256 th = sha3(rlpList(ss, tx.nonce()));
auto receipt = ethereum()->blockChain().receipts(h).receipts[txi];
s << "<h3>" << th << "</h3>";
s << "<h4>" << h << "[<b>" << txi << "</b>]</h4>";
s << "<br/>From: <b>" << pretty(ss).toHtmlEscaped().toStdString() << "</b> " << ss;
@ -1298,6 +1300,10 @@ void Main::on_blocks_currentItemChanged()
s << "<br/>R: <b>" << hex << nouppercase << tx.signature().r << "</b>";
s << "<br/>S: <b>" << hex << nouppercase << tx.signature().s << "</b>";
s << "<br/>Msg: <b>" << tx.sha3(eth::WithoutSignature) << "</b>";
s << "<div>Hex: <span style=\"font-family: Monospace,Lucida Console,Courier,Courier New,sans-serif; font-size: small\">" << toHex(block[1][txi].data()) << "</span></div>";
auto r = receipt.rlp();
s << "<div>Receipt: " << toString(RLP(r)) << "</div>";
s << "<div>Receipt-Hex: <span style=\"font-family: Monospace,Lucida Console,Courier,Courier New,sans-serif; font-size: small\">" << toHex(receipt.rlp()) << "</span></div>";
if (tx.isCreation())
{
if (tx.data().size())

2
alethzero/MainWin.h

@ -154,6 +154,7 @@ private slots:
void on_newIdentity_triggered();
void refreshWhisper();
void refreshBlockChain();
void addNewId(QString _ids);
signals:
@ -214,7 +215,6 @@ private:
void refreshPending();
void refreshAccounts();
void refreshDestination();
void refreshBlockChain();
void refreshBlockCount();
void refreshBalances();

96
exp/main.cpp

@ -36,7 +36,7 @@ using namespace dev::eth;
using namespace dev::p2p;
using namespace dev::shh;
#if 0
#if 1
int main()
{
DownloadMan man;
@ -44,18 +44,19 @@ int main()
DownloadSub s1(man);
DownloadSub s2(man);
man.resetToChain(h256s({u256(0), u256(1), u256(2), u256(3), u256(4), u256(5), u256(6), u256(7), u256(8)}));
cnote << s0.nextFetch(2);
cnote << s1.nextFetch(2);
cnote << s2.nextFetch(2);
s0.noteBlock(u256(0));
assert((s0.nextFetch(2) == h256Set{(u256)7, (u256)8}));
assert((s1.nextFetch(2) == h256Set{(u256)5, (u256)6}));
assert((s2.nextFetch(2) == h256Set{(u256)3, (u256)4}));
s0.noteBlock(u256(8));
s0.doneFetch();
cnote << s0.nextFetch(2);
s1.noteBlock(u256(2));
s1.noteBlock(u256(3));
assert((s0.nextFetch(2) == h256Set{(u256)2, (u256)7}));
s1.noteBlock(u256(6));
s1.noteBlock(u256(5));
s1.doneFetch();
cnote << s1.nextFetch(2);
s0.doneFetch();
cnote << s0.nextFetch(2);
assert((s1.nextFetch(2) == h256Set{(u256)0, (u256)1}));
s0.doneFetch(); // TODO: check exact semantics of doneFetch & nextFetch. Not sure if they're right -> doneFetch calls resetFetch which kills all the info of past fetches.
cdebug << s0.nextFetch(2);
assert((s0.nextFetch(2) == h256Set{(u256)3, (u256)4}));
/* RangeMask<unsigned> m(0, 100);
cnote << m;
@ -73,49 +74,70 @@ int main()
}
#endif
int main(int argc, char** argv)
/*int other(bool& o_started)
{
g_logVerbosity = 20;
short listenPort = 30303;
string remoteHost;
short remotePort = 30303;
setThreadName("other");
for (int i = 1; i < argc; ++i)
{
string arg = argv[i];
if (arg == "-l" && i + 1 < argc)
listenPort = (short)atoi(argv[++i]);
else if (arg == "-r" && i + 1 < argc)
remoteHost = argv[++i];
else if (arg == "-p" && i + 1 < argc)
remotePort = (short)atoi(argv[++i]);
else
remoteHost = argv[i];
}
short listenPort = 30300;
Host ph("Test", NetworkPreferences(listenPort, "", false, true));
auto wh = ph.registerCapability(new WhisperHost());
ph.start();
if (!remoteHost.empty())
ph.connect(remoteHost, remotePort);
o_started = true;
/// Only interested in odd packets
auto w = wh->installWatch(BuildTopicMask()("odd"));
KeyPair us = KeyPair::create();
for (int i = 0; ; ++i)
unsigned last = 0;
unsigned total = 0;
for (int i = 0; i < 100 && last < 81; ++i)
{
wh->post(us.sec(), RLPStream().append(i * i).out(), BuildTopic(i)(i % 2 ? "odd" : "even"));
for (auto i: wh->checkWatch(w))
{
Message msg = wh->envelope(i).open();
last = RLP(msg.payload()).toInt<unsigned>();
cnote << "New message from:" << msg.from().abridged() << RLP(msg.payload()).toInt<unsigned>();
total += last;
}
this_thread::sleep_for(chrono::seconds(1));
this_thread::sleep_for(chrono::milliseconds(50));
}
return 0;
return total;
}
int main(int, char**)
{
g_logVerbosity = 0;
bool started = false;
unsigned result;
std::thread listener([&](){ return (result = other(started)); });
while (!started)
this_thread::sleep_for(chrono::milliseconds(50));
short listenPort = 30303;
string remoteHost = "127.0.0.1";
short remotePort = 30300;
Host ph("Test", NetworkPreferences(listenPort, "", false, true));
auto wh = ph.registerCapability(new WhisperHost());
ph.start();
if (!remoteHost.empty())
ph.connect(remoteHost, remotePort);
KeyPair us = KeyPair::create();
for (int i = 0; i < 10; ++i)
{
wh->post(us.sec(), RLPStream().append(i * i).out(), BuildTopic(i)(i % 2 ? "odd" : "even"));
this_thread::sleep_for(chrono::milliseconds(250));
}
listener.join();
assert(result == 1 + 9 + 25 + 49 + 81);
return 0;
}*/

2
libdevcore/Common.cpp

@ -27,7 +27,7 @@ using namespace dev;
namespace dev
{
char const* Version = "0.7.9";
char const* Version = "0.7.10";
}

2
libdevcore/CommonIO.cpp

@ -30,7 +30,7 @@ string dev::memDump(bytes const& _b, unsigned _w, bool _html)
{
stringstream ret;
if (_html)
ret << "<pre style=\"font-family: Monospace, sans-serif; font-size: small\">";
ret << "<pre style=\"font-family: Monospace,Lucida Console,Courier,Courier New,sans-serif; font-size: small\">";
for (unsigned i = 0; i < _b.size(); i += _w)
{
ret << hex << setw(4) << setfill('0') << i << " ";

3
libdevcore/RLP.h

@ -158,6 +158,7 @@ public:
/// Best-effort conversion operators.
explicit operator std::string() const { return toString(); }
explicit operator bytes() const { return toBytes(); }
explicit operator RLPs() const { return toList(); }
explicit operator uint8_t() const { return toInt<uint8_t>(); }
explicit operator uint16_t() const { return toInt<uint16_t>(); }
@ -341,7 +342,7 @@ public:
RLPStream& append(char const* _s) { return append(std::string(_s)); }
template <unsigned N> RLPStream& append(FixedHash<N> _s, bool _compact = false, bool _allOrNothing = false) { return _allOrNothing && !_s ? append(bytesConstRef()) : append(_s.ref(), _compact); }
/// Appends an arbitrary RLP fragment - this *must* be a single item.
/// Appends an arbitrary RLP fragment - this *must* be a single item unless @a _itemCount is given.
RLPStream& append(RLP const& _rlp, unsigned _itemCount = 1) { return appendRaw(_rlp.data(), _itemCount); }
/// Appends a sequence of data to the stream as a list.

3
libdevcrypto/Common.cpp

@ -21,6 +21,7 @@
*/
#include <random>
#include <chrono>
#include <mutex>
#include "SHA3.h"
#include "FileSystem.h"
@ -85,7 +86,7 @@ bool dev::verify(Public _p, Signature _s, h256 _hash)
KeyPair KeyPair::create()
{
static mt19937_64 s_eng(time(0));
static mt19937_64 s_eng(time(0) + chrono::high_resolution_clock::now().time_since_epoch().count());
uniform_int_distribution<uint16_t> d(0, 255);
for (int i = 0; i < 100; ++i)

2
libethcore/CommonEth.cpp

@ -33,7 +33,7 @@ namespace dev
namespace eth
{
const unsigned c_protocolVersion = 39;
const unsigned c_protocolVersion = 40;
const unsigned c_databaseVersion = 4;
static const vector<pair<u256, string>> g_units =

7
libethereum/Executive.cpp

@ -123,11 +123,7 @@ bool Executive::call(Address _receiveAddress, Address _senderAddress, u256 _valu
m_ext = new ExtVM(m_s, _receiveAddress, _senderAddress, _originAddress, _value, _gasPrice, _data, &c, m_ms);
}
else
{
m_endGas = _gas;
if (m_ext)
m_ext->sub.logs.push_back(LogEntry(_receiveAddress, {u256((u160)_senderAddress) + 1}, bytes()));
}
return !m_ext;
}
@ -177,7 +173,10 @@ bool Executive::go(OnOpFunc const& _onOp)
{
m_out = m_vm->go(*m_ext, _onOp);
if (m_ext)
{
m_endGas += min((m_t.gas() - m_endGas) / 2, m_ext->sub.refunds);
m_logs = m_ext->sub.logs;
}
m_endGas = m_vm->gas();
}
catch (StepsDone const&)

22
libethereum/State.cpp

@ -21,9 +21,10 @@
#include "State.h"
#include <boost/filesystem.hpp>
#include <time.h>
#include <ctime>
#include <random>
#include <boost/filesystem.hpp>
#include <boost/timer.hpp>
#include <secp256k1/secp256k1.h>
#include <libdevcore/CommonIO.h>
#include <libevmcore/Instruction.h>
@ -549,10 +550,12 @@ h256s State::sync(TransactionQueue& _tq, bool* o_transactionQueueChanged)
try
{
uncommitToMine();
// boost::timer t;
execute(i.second);
ret.push_back(m_receipts.back().changes().bloom());
_tq.noteGood(i);
++goodTxs;
// cnote << "TX took:" << t.elapsed() * 1000;
}
catch (InvalidNonce const& in)
{
@ -1190,11 +1193,14 @@ bool State::call(Address _receiveAddress, Address _codeAddress, Address _senderA
auto it = !(_codeAddress & ~h160(0xffffffff)) ? c_precompiled.find((unsigned)(u160)_codeAddress) : c_precompiled.end();
if (it != c_precompiled.end())
{
if (*_gas >= it->second.gas)
if (*_gas < it->second.gas)
{
*_gas -= it->second.gas;
it->second.exec(_data, _out);
*_gas = 0;
return false;
}
*_gas -= it->second.gas;
it->second.exec(_data, _out);
}
else if (addressHasCode(_codeAddress))
{
@ -1235,12 +1241,6 @@ bool State::call(Address _receiveAddress, Address _codeAddress, Address _senderA
return !revert;
}
else
{
// non-contract call
if (o_sub)
o_sub->logs.push_back(LogEntry(_receiveAddress, {u256((u160)_senderAddress) + 1}, bytes()));
}
return true;
}

2
libethereum/TransactionReceipt.h

@ -55,6 +55,8 @@ public:
l.streamRLP(_s);
}
bytes rlp() const { RLPStream s; streamRLP(s); return s.out(); }
private:
h256 m_stateRoot;
u256 m_gasUsed;

26
libevm/VM.h

@ -206,7 +206,7 @@ template <class Ext> dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
{
unsigned n = (unsigned)inst - (unsigned)Instruction::LOG0;
require(n + 2);
newTempSize = memNeed(m_stack[m_stack.size() - 1 - n], m_stack[m_stack.size() - 2 - n]);
newTempSize = memNeed(m_stack[m_stack.size() - 1 ], m_stack[m_stack.size() - 2]);
break;
}
@ -701,7 +701,7 @@ template <class Ext> dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
break;
case Instruction::JUMP:
nextPC = m_stack.back();
if (!m_jumpDests.count((unsigned)nextPC))
if (!m_jumpDests.count(nextPC))
BOOST_THROW_EXCEPTION(BadJumpDestination());
m_stack.pop_back();
break;
@ -709,7 +709,7 @@ template <class Ext> dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
if (m_stack[m_stack.size() - 2])
{
nextPC = m_stack.back();
if (!m_jumpDests.count((unsigned)nextPC))
if (!m_jumpDests.count(nextPC))
BOOST_THROW_EXCEPTION(BadJumpDestination());
}
m_stack.pop_back();
@ -743,18 +743,38 @@ template <class Ext> dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
break;*/
case Instruction::LOG0:
_ext.log({}, bytesConstRef(m_temp.data() + (unsigned)m_stack[m_stack.size() - 1], (unsigned)m_stack[m_stack.size() - 2]));
m_stack.pop_back();
m_stack.pop_back();
break;
case Instruction::LOG1:
_ext.log({m_stack[m_stack.size() - 3]}, bytesConstRef(m_temp.data() + (unsigned)m_stack[m_stack.size() - 1], (unsigned)m_stack[m_stack.size() - 2]));
m_stack.pop_back();
m_stack.pop_back();
m_stack.pop_back();
break;
case Instruction::LOG2:
_ext.log({m_stack[m_stack.size() - 3], m_stack[m_stack.size() - 4]}, bytesConstRef(m_temp.data() + (unsigned)m_stack[m_stack.size() - 1], (unsigned)m_stack[m_stack.size() - 2]));
m_stack.pop_back();
m_stack.pop_back();
m_stack.pop_back();
m_stack.pop_back();
break;
case Instruction::LOG3:
_ext.log({m_stack[m_stack.size() - 3], m_stack[m_stack.size() - 4], m_stack[m_stack.size() - 5]}, bytesConstRef(m_temp.data() + (unsigned)m_stack[m_stack.size() - 1], (unsigned)m_stack[m_stack.size() - 2]));
m_stack.pop_back();
m_stack.pop_back();
m_stack.pop_back();
m_stack.pop_back();
m_stack.pop_back();
break;
case Instruction::LOG4:
_ext.log({m_stack[m_stack.size() - 3], m_stack[m_stack.size() - 4], m_stack[m_stack.size() - 5], m_stack[m_stack.size() - 6]}, bytesConstRef(m_temp.data() + (unsigned)m_stack[m_stack.size() - 1], (unsigned)m_stack[m_stack.size() - 2]));
m_stack.pop_back();
m_stack.pop_back();
m_stack.pop_back();
m_stack.pop_back();
m_stack.pop_back();
m_stack.pop_back();
break;
case Instruction::CREATE:
{

12
libevmcore/Instruction.cpp

@ -282,11 +282,11 @@ static const std::map<Instruction, InstructionInfo> c_instructionInfo =
{ Instruction::SWAP14, { "SWAP14", 0, 15, 15, false } },
{ Instruction::SWAP15, { "SWAP15", 0, 16, 16, false } },
{ Instruction::SWAP16, { "SWAP16", 0, 17, 17, false } },
{ Instruction::LOG0, { "LOG0", 0, 1, 0, true } },
{ Instruction::LOG1, { "LOG1", 0, 2, 0, true } },
{ Instruction::LOG2, { "LOG2", 0, 3, 0, true } },
{ Instruction::LOG3, { "LOG3", 0, 4, 0, true } },
{ Instruction::LOG4, { "LOG4", 0, 5, 0, true } },
{ Instruction::LOG0, { "LOG0", 0, 2, 0, true } },
{ Instruction::LOG1, { "LOG1", 0, 3, 0, true } },
{ Instruction::LOG2, { "LOG2", 0, 4, 0, true } },
{ Instruction::LOG3, { "LOG3", 0, 5, 0, true } },
{ Instruction::LOG4, { "LOG4", 0, 6, 0, true } },
{ Instruction::CREATE, { "CREATE", 0, 3, 1, true } },
{ Instruction::CALL, { "CALL", 0, 7, 1, true } },
{ Instruction::CALLCODE, { "CALLCODE", 0, 7, 1, true } },
@ -327,7 +327,7 @@ InstructionInfo dev::eth::instructionInfo(Instruction _inst)
catch (...)
{
cwarn << "<INVALID_INSTRUCTION: " << toString((unsigned)_inst) << ">\n" << boost::current_exception_diagnostic_information();
return InstructionInfo({"<INVALID_INSTRUCTION: " + toString((unsigned)_inst) + ">", 0, 0, 0});
return InstructionInfo({"<INVALID_INSTRUCTION: " + toString((unsigned)_inst) + ">", 0, 0, 0, false});
}
}

2
libwhisper/Common.h

@ -92,7 +92,7 @@ public:
TopicFilter() {}
TopicFilter(TopicMask const& _m): m_topicMasks(1, _m) {}
TopicFilter(TopicMasks const& _m): m_topicMasks(_m) {}
TopicFilter(RLP const& _r): m_topicMasks((TopicMasks)_r) {}
TopicFilter(RLP const& _r): m_topicMasks(_r.toVector<std::vector<std::pair<uint32_t, uint32_t>>>()) {}
void streamRLP(RLPStream& _s) const { _s << m_topicMasks; }
h256 sha3() const;

2
libwhisper/Message.h

@ -55,7 +55,7 @@ public:
{
m_expiry = _m[0].toInt<unsigned>();
m_ttl = _m[1].toInt<unsigned>();
m_topic = (Topic)_m[2];
m_topic = _m[2].toVector<uint32_t>();
m_data = _m[3].toBytes();
m_nonce = _m[4].toInt<u256>();
}

9
test/createRandomTest.cpp

@ -32,6 +32,7 @@
#include <libdevcore/CommonIO.h>
#include <libdevcore/CommonData.h>
#include <libevmcore/Instruction.h>
#include <libevm/VM.h>
#include "vm.h"
using namespace std;
@ -142,10 +143,16 @@ void doMyTests(json_spirit::mValue& v)
vm.reset(fev.gas);
bytes output;
u256 gas;
try
{
output = vm.go(fev).toBytes();
}
catch (eth::VMException const& _e)
{
cnote << "VM did throw an exception: " << diagnostic_information(_e);
gas = 0;
}
catch (Exception const& _e)
{
cnote << "VM did throw an exception: " << diagnostic_information(_e);
@ -176,6 +183,6 @@ void doMyTests(json_spirit::mValue& v)
o["post"] = mValue(fev.exportState());
o["callcreates"] = fev.exportCallCreates();
o["out"] = "0x" + toHex(output);
fev.push(o, "gas", vm.gas());
fev.push(o, "gas", gas);
}
}

16
test/vm.cpp

@ -298,19 +298,27 @@ void doVMTests(json_spirit::mValue& v, bool _fillin)
bytes output;
VM vm(fev.gas);
u256 gas;
try
{
output = vm.go(fev, fev.simpleTrace()).toVector();
gas = vm.gas();
}
catch (VMException const& _e)
{
cnote << "VM did throw an exception: " << diagnostic_information(_e);
gas = 0;
}
catch (Exception const& _e)
{
cnote << "VM did throw an exception: " << diagnostic_information(_e);
//BOOST_ERROR("Failed VM Test with Exception: " << e.what());
BOOST_ERROR("Failed VM Test with Exception: " << _e.what());
}
catch (std::exception const& _e)
{
cnote << "VM did throw an exception: " << _e.what();
//BOOST_ERROR("Failed VM Test with Exception: " << e.what());
BOOST_ERROR("Failed VM Test with Exception: " << _e.what());
}
// delete null entries in storage for the sake of comparison
@ -337,7 +345,7 @@ void doVMTests(json_spirit::mValue& v, bool _fillin)
o["post"] = mValue(fev.exportState());
o["callcreates"] = fev.exportCallCreates();
o["out"] = "0x" + toHex(output);
fev.push(o, "gas", vm.gas());
fev.push(o, "gas", gas);
}
else
{
@ -352,7 +360,7 @@ void doVMTests(json_spirit::mValue& v, bool _fillin)
checkOutput(output, o);
BOOST_CHECK_EQUAL(toInt(o["gas"]), vm.gas());
BOOST_CHECK_EQUAL(toInt(o["gas"]), gas);
auto& expectedAddrs = test.addresses;
auto& resultAddrs = fev.addresses;

84
test/whisperTopic.cpp

@ -0,0 +1,84 @@
/*
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 whisperTopic.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#include <functional>
#include <boost/test/unit_test.hpp>
#include <libp2p/Host.h>
#include <libwhisper/WhisperPeer.h>
#include <libwhisper/WhisperHost.h>
using namespace std;
using namespace dev;
using namespace dev::p2p;
using namespace dev::shh;
BOOST_AUTO_TEST_SUITE(whisper)
BOOST_AUTO_TEST_CASE(topic)
{
g_logVerbosity = 0;
bool started = false;
unsigned result = 0;
std::thread listener([&]()
{
setThreadName("other");
Host ph("Test", NetworkPreferences(30303, "", false, true));
auto wh = ph.registerCapability(new WhisperHost());
ph.start();
started = true;
/// Only interested in odd packets
auto w = wh->installWatch(BuildTopicMask()("odd"));
for (int i = 0, last = 0; i < 100 && last < 81; ++i)
{
for (auto i: wh->checkWatch(w))
{
Message msg = wh->envelope(i).open();
last = RLP(msg.payload()).toInt<unsigned>();
cnote << "New message from:" << msg.from().abridged() << RLP(msg.payload()).toInt<unsigned>();
result += last;
}
this_thread::sleep_for(chrono::milliseconds(50));
}
});
while (!started)
this_thread::sleep_for(chrono::milliseconds(50));
Host ph("Test", NetworkPreferences(30300, "", false, true));
auto wh = ph.registerCapability(new WhisperHost());
ph.start();
ph.connect("127.0.0.1", 30303);
KeyPair us = KeyPair::create();
for (int i = 0; i < 10; ++i)
{
wh->post(us.sec(), RLPStream().append(i * i).out(), BuildTopic(i)(i % 2 ? "odd" : "even"));
this_thread::sleep_for(chrono::milliseconds(250));
}
listener.join();
BOOST_REQUIRE_EQUAL(result, 1 + 9 + 25 + 49 + 81);
}
BOOST_AUTO_TEST_SUITE_END()
Loading…
Cancel
Save