Browse Source

Merge branch 'develop' of https://github.com/ethereum/cpp-ethereum into mix_ux

cl-refactor
arkpar 10 years ago
parent
commit
e9bf85208f
  1. 5
      libethereum/Client.cpp
  2. 43
      libethereum/State.cpp
  3. 7
      libethereum/State.h
  4. 3
      libjsqrc/ethereumjs/dist/ethereum.js
  5. 4
      libjsqrc/ethereumjs/dist/ethereum.js.map
  6. 2
      libjsqrc/ethereumjs/dist/ethereum.min.js
  7. 3
      libjsqrc/ethereumjs/lib/filter.js
  8. 2
      libsolidity/AST.h
  9. 2
      mix/CMakeLists.txt
  10. 12
      mix/ClientModel.cpp
  11. 14
      mix/MixClient.cpp
  12. 1
      mix/MixClient.h
  13. 2
      mix/Web3Server.cpp
  14. 4
      mix/qml/js/ProjectModel.js
  15. 42
      test/SolidityABIJSON.cpp
  16. 173
      test/SolidityInterface.cpp
  17. 4
      test/stateOriginal.cpp
  18. 4
      test/whisperTopic.cpp

5
libethereum/Client.cpp

@ -361,12 +361,13 @@ void Client::setupState(State& _s)
cwork << "SETUP MINE";
_s = m_postMine;
}
_s.setUncles(m_bc);
if (m_paranoia)
{
if (_s.amIJustParanoid(m_bc))
{
cnote << "I'm just paranoid. Block is fine.";
_s.commitToMine(m_bc);
_s.commitToMine();
}
else
{
@ -374,7 +375,7 @@ void Client::setupState(State& _s)
}
}
else
_s.commitToMine(m_bc);
_s.commitToMine();
}
void Client::transact(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice)

43
libethereum/State.cpp

@ -639,7 +639,8 @@ void State::uncommitToMine()
bool State::amIJustParanoid(BlockChain const& _bc)
{
commitToMine(_bc);
setUncles(_bc);
commitToMine();
// Update difficulty according to timestamp.
m_currentBlock.difficulty = m_currentBlock.calculateDifficulty(m_previousBlock);
@ -682,22 +683,8 @@ LogBloom State::logBloom() const
return ret;
}
// @returns the block that represents the difference between m_previousBlock and m_currentBlock.
// (i.e. all the transactions we executed).
void State::commitToMine(BlockChain const& _bc)
void State::setUncles(BlockChain const& _bc)
{
uncommitToMine();
// cnote << "Committing to mine on block" << m_previousBlock.hash.abridged();
#ifdef ETH_PARANOIA
commit();
cnote << "Pre-reward stateRoot:" << m_state.root();
#endif
m_lastTx = m_db;
Addresses uncleAddresses;
RLPStream unclesData;
unsigned unclesCount = 0;
if (m_previousBlock != BlockChain::genesis())
@ -716,11 +703,26 @@ void State::commitToMine(BlockChain const& _bc)
BlockInfo ubi(_bc.block(u));
ubi.streamRLP(unclesData, WithNonce);
++unclesCount;
uncleAddresses.push_back(ubi.coinbaseAddress);
}
}
}
RLPStream(unclesCount).appendRaw(unclesData.out(), unclesCount).swapOut(m_currentUncles);
m_currentBlock.sha3Uncles = sha3(m_currentUncles);
}
void State::commitToMine()
{
uncommitToMine();
// cnote << "Committing to mine on block" << m_previousBlock.hash.abridged();
#ifdef ETH_PARANOIA
commit();
cnote << "Pre-reward stateRoot:" << m_state.root();
#endif
m_lastTx = m_db;
MemoryDB tm;
GenericTrieDB<MemoryDB> transactionsTrie(&tm);
transactionsTrie.init();
@ -750,12 +752,13 @@ void State::commitToMine(BlockChain const& _bc)
txs.swapOut(m_currentTxs);
RLPStream(unclesCount).appendRaw(unclesData.out(), unclesCount).swapOut(m_currentUncles);
m_currentBlock.transactionsRoot = transactionsTrie.root();
m_currentBlock.receiptsRoot = receiptsTrie.root();
m_currentBlock.logBloom = logBloom();
m_currentBlock.sha3Uncles = sha3(m_currentUncles);
Addresses uncleAddresses;
for (const auto& r: RLP(m_currentUncles))
uncleAddresses.push_back(BlockInfo::fromHeader(r.data()).coinbaseAddress);
// Apply rewards last of all.
applyRewards(uncleAddresses);

7
libethereum/State.h

@ -105,13 +105,16 @@ public:
/// @returns true if all is ok. If it's false, worry.
bool amIJustParanoid(BlockChain const& _bc);
/// @brief Loads current block uncles from blockchain
void setUncles(BlockChain const& _bc);
/// Prepares the current state for mining.
/// Commits all transactions into the trie, compiles uncles and transactions list, applies all
/// rewards and populates the current block header with the appropriate hashes.
/// The only thing left to do after this is to actually mine().
///
/// This may be called multiple times and without issue.
void commitToMine(BlockChain const& _bc);
void commitToMine();
/// Attempt to find valid nonce for block that this state represents.
/// This function is thread-safe. You can safely have other interactions with this object while it is happening.
@ -123,7 +126,7 @@ public:
* Typically looks like:
* @code
* // lock
* commitToMine(blockchain);
* commitToMine();
* // unlock
* MineInfo info;
* for (info.complete = false; !info.complete; info = mine()) {}

3
libjsqrc/ethereumjs/dist/ethereum.js

@ -590,6 +590,9 @@ var Filter = function(options, impl) {
Filter.prototype.arrived = function(callback) {
this.changed(callback);
};
Filter.prototype.happened = function(callback) {
this.changed(callback);
};
/// gets called when there is new eth/shh message
Filter.prototype.changed = function(callback) {

4
libjsqrc/ethereumjs/dist/ethereum.js.map

File diff suppressed because one or more lines are too long

2
libjsqrc/ethereumjs/dist/ethereum.min.js

File diff suppressed because one or more lines are too long

3
libjsqrc/ethereumjs/lib/filter.js

@ -61,6 +61,9 @@ var Filter = function(options, impl) {
Filter.prototype.arrived = function(callback) {
this.changed(callback);
};
Filter.prototype.happened = function(callback) {
this.changed(callback);
};
/// gets called when there is new eth/shh message
Filter.prototype.changed = function(callback) {

2
libsolidity/AST.h

@ -487,7 +487,6 @@ public:
std::vector<ASTPointer<VariableDeclaration>> const& getParameters() const { return m_parameters->getParameters(); }
ParameterList const& getParameterList() const { return *m_parameters; }
Block const& getBody() const { return *m_body; }
virtual TypePointer getType(ContractDefinition const* = nullptr) const override
{
@ -498,7 +497,6 @@ public:
private:
ASTPointer<ParameterList> m_parameters;
ASTPointer<Block> m_body;
};
/**

2
mix/CMakeLists.txt

@ -26,6 +26,8 @@ else()
qt5_add_resources(UI_RESOURCES noweb.qrc)
endif()
add_definitions(-DQT_QML_DEBUG)
# eth_add_executable is defined in cmake/EthExecutableHelper.cmake
eth_add_executable(${EXECUTABLE}
ICON mix

12
mix/ClientModel.cpp

@ -93,8 +93,16 @@ ClientModel::~ClientModel()
QString ClientModel::apiCall(QString const& _message)
{
m_rpcConnector->OnRequest(_message.toStdString(), nullptr);
return m_rpcConnector->response();
try
{
m_rpcConnector->OnRequest(_message.toStdString(), nullptr);
return m_rpcConnector->response();
}
catch (...)
{
std::cerr << boost::current_exception_diagnostic_information();
return QString();
}
}
void ClientModel::mine()

14
mix/MixClient.cpp

@ -50,18 +50,22 @@ void MixClient::resetState(u256 _balance)
Guard fl(m_filterLock);
m_filters.clear();
m_watches.clear();
m_state = eth::State(m_userAccount.address(), m_stateDB, BaseState::Empty);
m_state = eth::State(m_userAccount.address(), m_stateDB, BaseState::Genesis);
m_state.addBalance(m_userAccount.address(), _balance);
Block genesis;
genesis.state = m_state;
Block open;
m_blocks = Blocks { genesis, open }; //last block contains a list of pending transactions to be finalized
m_lastHashes.clear();
m_lastHashes.resize(256);
m_lastHashes[0] = genesis.hash;
}
void MixClient::executeTransaction(Transaction const& _t, State& _state)
{
bytes rlp = _t.rlp();
Executive execution(_state, LastHashes(), 0);
Executive execution(_state, m_lastHashes, 0);
execution.setup(&rlp);
std::vector<MachineState> machineStates;
std::vector<unsigned> levels;
@ -159,11 +163,17 @@ void MixClient::mine()
{
WriteGuard l(x_state);
Block& block = m_blocks.back();
m_state.mine(0, true);
m_state.completeMine();
m_state.commitToMine();
block.state = m_state;
block.info = m_state.info();
block.hash = block.info.hash;
m_state.cleanup(true);
m_blocks.push_back(Block());
m_lastHashes.insert(m_lastHashes.begin(), block.hash);
m_lastHashes.resize(256);
h256Set changed { dev::eth::PendingChangedFilter, dev::eth::ChainChangedFilter };
noteChanged(changed);
}

1
mix/MixClient.h

@ -145,6 +145,7 @@ private:
std::map<h256, dev::eth::InstalledFilter> m_filters;
std::map<unsigned, dev::eth::ClientWatch> m_watches;
Blocks m_blocks;
eth::LastHashes m_lastHashes;
};
}

2
mix/Web3Server.cpp

@ -57,8 +57,6 @@ void Web3Server::put(std::string const& _name, std::string const& _key, std::str
Json::Value Web3Server::eth_changed(int const& _id)
{
cnote << "eth_changed(" << _id << ") ->" << client()->peekWatch(_id).size();
return WebThreeStubServerBase::eth_changed(_id);
}

4
mix/qml/js/ProjectModel.js

@ -172,8 +172,8 @@ function doCreateProject(title, path) {
files: [ contractsFile, indexFile ]
};
//TODO: copy from template
fileIo.writeFile(dirPath + indexFile, "<html></html>");
fileIo.writeFile(dirPath + contractsFile, "contract MyContract {\n}\n");
fileIo.writeFile(dirPath + indexFile, "<html>\n<head>\n<script>\nvar web3 = parent.web3;\nvar theContract = parent.contract;\n</script>\n</head>\n<body>\n<script>\n</script>\n</body>\n</html>");
fileIo.writeFile(dirPath + contractsFile, "contract Contract {\n}\n");
newProject(projectData);
var json = JSON.stringify(projectData, null, "\t");
fileIo.writeFile(projectFile, json);

42
test/SolidityABIJSON.cpp

@ -32,12 +32,12 @@ namespace solidity
namespace test
{
class InterfaceChecker
class JSONInterfaceChecker
{
public:
InterfaceChecker(): m_compilerStack(false) {}
JSONInterfaceChecker(): m_compilerStack(false) {}
void checkInterface(std::string const& _code, std::string const& _expectedInterfaceString, std::string const& expectedSolidityInterface)
void checkInterface(std::string const& _code, std::string const& _expectedInterfaceString)
{
try
{
@ -49,7 +49,6 @@ public:
BOOST_FAIL(msg);
}
std::string generatedInterfaceString = m_compilerStack.getMetadata("", DocumentationType::ABI_INTERFACE);
std::string generatedSolidityInterfaceString = m_compilerStack.getMetadata("", DocumentationType::ABI_SOLIDITY_INTERFACE);
Json::Value generatedInterface;
m_reader.parse(generatedInterfaceString, generatedInterface);
Json::Value expectedInterface;
@ -57,9 +56,6 @@ public:
BOOST_CHECK_MESSAGE(expectedInterface == generatedInterface,
"Expected:\n" << expectedInterface.toStyledString() <<
"\n but got:\n" << generatedInterface.toStyledString());
BOOST_CHECK_MESSAGE(expectedSolidityInterface == generatedSolidityInterfaceString,
"Expected:\n" << expectedSolidityInterface <<
"\n but got:\n" << generatedSolidityInterfaceString);
}
private:
@ -67,7 +63,7 @@ private:
Json::Reader m_reader;
};
BOOST_FIXTURE_TEST_SUITE(SolidityABIJSON, InterfaceChecker)
BOOST_FIXTURE_TEST_SUITE(SolidityABIJSON, JSONInterfaceChecker)
BOOST_AUTO_TEST_CASE(basic_test)
{
@ -75,8 +71,6 @@ BOOST_AUTO_TEST_CASE(basic_test)
" function f(uint a) returns(uint d) { return a * 7; }\n"
"}\n";
char const* sourceInterface = "contract test{function f(uint256 a)returns(uint256 d){}}";
char const* interface = R"([
{
"name": "f",
@ -97,18 +91,16 @@ BOOST_AUTO_TEST_CASE(basic_test)
}
])";
checkInterface(sourceCode, interface, sourceInterface);
checkInterface(sourceCode, interface);
}
BOOST_AUTO_TEST_CASE(empty_contract)
{
char const* sourceCode = "contract test {\n"
"}\n";
char const* sourceInterface = "contract test{}";
char const* interface = "[]";
checkInterface(sourceCode, interface, sourceInterface);
checkInterface(sourceCode, interface);
}
BOOST_AUTO_TEST_CASE(multiple_methods)
@ -117,7 +109,6 @@ BOOST_AUTO_TEST_CASE(multiple_methods)
" function f(uint a) returns(uint d) { return a * 7; }\n"
" function g(uint b) returns(uint e) { return b * 8; }\n"
"}\n";
char const* sourceInterface = "contract test{function f(uint256 a)returns(uint256 d){}function g(uint256 b)returns(uint256 e){}}";
char const* interface = R"([
{
@ -156,7 +147,7 @@ BOOST_AUTO_TEST_CASE(multiple_methods)
}
])";
checkInterface(sourceCode, interface, sourceInterface);
checkInterface(sourceCode, interface);
}
BOOST_AUTO_TEST_CASE(multiple_params)
@ -164,7 +155,6 @@ BOOST_AUTO_TEST_CASE(multiple_params)
char const* sourceCode = "contract test {\n"
" function f(uint a, uint b) returns(uint d) { return a + b; }\n"
"}\n";
char const* sourceInterface = "contract test{function f(uint256 a,uint256 b)returns(uint256 d){}}";
char const* interface = R"([
{
@ -190,7 +180,7 @@ BOOST_AUTO_TEST_CASE(multiple_params)
}
])";
checkInterface(sourceCode, interface, sourceInterface);
checkInterface(sourceCode, interface);
}
BOOST_AUTO_TEST_CASE(multiple_methods_order)
@ -200,7 +190,6 @@ BOOST_AUTO_TEST_CASE(multiple_methods_order)
" function f(uint a) returns(uint d) { return a * 7; }\n"
" function c(uint b) returns(uint e) { return b * 8; }\n"
"}\n";
char const* sourceInterface = "contract test{function c(uint256 b)returns(uint256 e){}function f(uint256 a)returns(uint256 d){}}";
char const* interface = R"([
{
@ -239,7 +228,7 @@ BOOST_AUTO_TEST_CASE(multiple_methods_order)
}
])";
checkInterface(sourceCode, interface, sourceInterface);
checkInterface(sourceCode, interface);
}
BOOST_AUTO_TEST_CASE(const_function)
@ -248,7 +237,6 @@ BOOST_AUTO_TEST_CASE(const_function)
" function foo(uint a, uint b) returns(uint d) { return a + b; }\n"
" function boo(uint32 a) constant returns(uint b) { return a * 4; }\n"
"}\n";
char const* sourceInterface = "contract test{function foo(uint256 a,uint256 b)returns(uint256 d){}function boo(uint32 a)constant returns(uint256 b){}}";
char const* interface = R"([
{
@ -289,17 +277,16 @@ BOOST_AUTO_TEST_CASE(const_function)
}
])";
checkInterface(sourceCode, interface, sourceInterface);
checkInterface(sourceCode, interface);
}
BOOST_AUTO_TEST_CASE(exclude_fallback_function)
{
char const* sourceCode = "contract test { function() {} }";
char const* sourceInterface = "contract test{}";
char const* interface = "[]";
checkInterface(sourceCode, interface, sourceInterface);
checkInterface(sourceCode, interface);
}
BOOST_AUTO_TEST_CASE(events)
@ -309,8 +296,6 @@ BOOST_AUTO_TEST_CASE(events)
" event e1(uint b, address indexed c); \n"
" event e2(); \n"
"}\n";
char const* sourceInterface = "contract test{function f(uint256 a)returns(uint256 d){}event e1(uint256 b,address indexed c);event e2;}";
char const* interface = R"([
{
"name": "f",
@ -353,7 +338,7 @@ BOOST_AUTO_TEST_CASE(events)
])";
checkInterface(sourceCode, interface, sourceInterface);
checkInterface(sourceCode, interface);
}
@ -368,7 +353,6 @@ BOOST_AUTO_TEST_CASE(inherited)
" function derivedFunction(string32 p) returns (string32 i) { return p; } \n"
" event derivedEvent(uint indexed evtArgDerived); \n"
" }";
char const* sourceInterface = "contract Derived{function baseFunction(uint256 p)returns(uint256 i){}function derivedFunction(string32 p)returns(string32 i){}event derivedEvent(uint256 indexed evtArgDerived);event baseEvent(string32 indexed evtArgBase);}";
char const* interface = R"([
{
@ -423,7 +407,7 @@ BOOST_AUTO_TEST_CASE(inherited)
}])";
checkInterface(sourceCode, interface, sourceInterface);
checkInterface(sourceCode, interface);
}

173
test/SolidityInterface.cpp

@ -0,0 +1,173 @@
/*
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/>.
*/
/**
* @author Christian <c@ethdev.com>
* @date 2015
* Unit tests for generating source interfaces for Solidity contracts.
*/
#include <boost/test/unit_test.hpp>
#include <libsolidity/CompilerStack.h>
#include <libsolidity/AST.h>
using namespace std;
namespace dev
{
namespace solidity
{
namespace test
{
class SolidityInterfaceChecker
{
public:
SolidityInterfaceChecker(): m_compilerStack(false) {}
/// Compiles the given code, generates the interface and parses that again.
ContractDefinition const& checkInterface(string const& _code, string const& _contractName = "")
{
m_code = _code;
BOOST_REQUIRE_NO_THROW(m_compilerStack.parse(_code));
m_interface = m_compilerStack.getMetadata("", DocumentationType::ABI_SOLIDITY_INTERFACE);
BOOST_REQUIRE_NO_THROW(m_reCompiler.parse(m_interface));
return m_reCompiler.getContractDefinition(_contractName);
}
string getSourcePart(ASTNode const& _node) const
{
Location location = _node.getLocation();
BOOST_REQUIRE(!location.isEmpty());
return m_interface.substr(location.start, location.end - location.start);
}
protected:
string m_code;
string m_interface;
CompilerStack m_compilerStack;
CompilerStack m_reCompiler;
};
BOOST_FIXTURE_TEST_SUITE(SolidityInterface, SolidityInterfaceChecker)
BOOST_AUTO_TEST_CASE(empty_contract)
{
ContractDefinition const& contract = checkInterface("contract test {}");
BOOST_CHECK_EQUAL(getSourcePart(contract), "contract test{}");
}
BOOST_AUTO_TEST_CASE(single_function)
{
ContractDefinition const& contract = checkInterface(
"contract test {\n"
" function f(uint a) returns(uint d) { return a * 7; }\n"
"}\n");
BOOST_REQUIRE_EQUAL(1, contract.getDefinedFunctions().size());
BOOST_CHECK_EQUAL(getSourcePart(*contract.getDefinedFunctions().front()),
"function f(uint256 a)returns(uint256 d){}");
}
BOOST_AUTO_TEST_CASE(single_constant_function)
{
ContractDefinition const& contract = checkInterface(
"contract test { function f(uint a) constant returns(hash8 x) { 1==2; } }");
BOOST_REQUIRE_EQUAL(1, contract.getDefinedFunctions().size());
BOOST_CHECK_EQUAL(getSourcePart(*contract.getDefinedFunctions().front()),
"function f(uint256 a)constant returns(hash8 x){}");
}
BOOST_AUTO_TEST_CASE(multiple_functions)
{
char const* sourceCode = "contract test {\n"
" function f(uint a) returns(uint d) { return a * 7; }\n"
" function g(uint b) returns(uint e) { return b * 8; }\n"
"}\n";
ContractDefinition const& contract = checkInterface(sourceCode);
set<string> expectation({"function f(uint256 a)returns(uint256 d){}",
"function g(uint256 b)returns(uint256 e){}"});
BOOST_REQUIRE_EQUAL(2, contract.getDefinedFunctions().size());
BOOST_CHECK(expectation == set<string>({getSourcePart(*contract.getDefinedFunctions().at(0)),
getSourcePart(*contract.getDefinedFunctions().at(1))}));
}
BOOST_AUTO_TEST_CASE(exclude_fallback_function)
{
char const* sourceCode = "contract test { function() {} }";
ContractDefinition const& contract = checkInterface(sourceCode);
BOOST_CHECK_EQUAL(getSourcePart(contract), "contract test{}");
}
BOOST_AUTO_TEST_CASE(event)
{
ContractDefinition const& contract = checkInterface(
"contract test { event Event; }");
BOOST_REQUIRE_EQUAL(1, contract.getEvents().size());
BOOST_CHECK_EQUAL(getSourcePart(*contract.getEvents().front()),
"event Event;");
}
BOOST_AUTO_TEST_CASE(event_arguments)
{
ContractDefinition const& contract = checkInterface(
"contract test { event Event(uint a, uint indexed b); }");
BOOST_REQUIRE_EQUAL(1, contract.getEvents().size());
BOOST_CHECK_EQUAL(getSourcePart(*contract.getEvents().front()),
"event Event(uint256 a,uint256 indexed b);");
}
BOOST_AUTO_TEST_CASE(events)
{
char const* sourceCode = "contract test {\n"
" function f(uint a) returns(uint d) { return a * 7; }\n"
" event e1(uint b, address indexed c); \n"
" event e2(); \n"
"}\n";
ContractDefinition const& contract = checkInterface(sourceCode);
set<string> expectation({"event e1(uint256 b,address indexed c);", "event e2;"});
BOOST_REQUIRE_EQUAL(2, contract.getEvents().size());
BOOST_CHECK(expectation == set<string>({getSourcePart(*contract.getEvents().at(0)),
getSourcePart(*contract.getEvents().at(1))}));
}
BOOST_AUTO_TEST_CASE(inheritance)
{
char const* sourceCode =
" contract Base { \n"
" function baseFunction(uint p) returns (uint i) { return p; } \n"
" event baseEvent(string32 indexed evtArgBase); \n"
" } \n"
" contract Derived is Base { \n"
" function derivedFunction(string32 p) returns (string32 i) { return p; } \n"
" event derivedEvent(uint indexed evtArgDerived); \n"
" }";
ContractDefinition const& contract = checkInterface(sourceCode);
set<string> expectedEvents({"event derivedEvent(uint256 indexed evtArgDerived);",
"event baseEvent(string32 indexed evtArgBase);"});
set<string> expectedFunctions({"function baseFunction(uint256 p)returns(uint256 i){}",
"function derivedFunction(string32 p)returns(string32 i){}"});
BOOST_CHECK(expectedEvents == set<string>({getSourcePart(*contract.getEvents().at(0)),
getSourcePart(*contract.getEvents().at(1))}));
BOOST_REQUIRE_EQUAL(2, contract.getDefinedFunctions().size());
BOOST_CHECK(expectedFunctions == set<string>({getSourcePart(*contract.getDefinedFunctions().at(0)),
getSourcePart(*contract.getDefinedFunctions().at(1))}));
}
BOOST_AUTO_TEST_SUITE_END()
}
}
}

4
test/stateOriginal.cpp

@ -51,7 +51,7 @@ int stateTest()
cout << s;
// Mine to get some ether!
s.commitToMine(bc);
s.commitToMine();
while (!s.mine(100).completed) {}
s.completeMine();
bc.attemptImport(s.blockData(), stateDB);
@ -74,7 +74,7 @@ int stateTest()
cout << s;
// Mine to get some ether and set in stone.
s.commitToMine(bc);
s.commitToMine();
while (!s.mine(100).completed) {}
s.completeMine();
bc.attemptImport(s.blockData(), stateDB);

4
test/whisperTopic.cpp

@ -50,6 +50,7 @@ BOOST_AUTO_TEST_CASE(topic)
auto w = wh->installWatch(BuildTopicMask("odd"));
started = true;
set<unsigned> received;
for (int iterout = 0, last = 0; iterout < 200 && last < 81; ++iterout)
{
@ -57,6 +58,9 @@ BOOST_AUTO_TEST_CASE(topic)
{
Message msg = wh->envelope(i).open(wh->fullTopic(w));
last = RLP(msg.payload()).toInt<unsigned>();
if (received.count(last))
continue;
received.insert(last);
cnote << "New message from:" << msg.from().abridged() << RLP(msg.payload()).toInt<unsigned>();
result += last;
}

Loading…
Cancel
Save