diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index cd6cad11a..343097bbf 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -50,6 +50,7 @@ #include "MiningView.h" #include "BuildInfo.h" #include "MainWin.h" +#include "OurWebThreeStubServer.h" #include "ui_Main.h" using namespace std; using namespace dev; @@ -154,7 +155,8 @@ Main::Main(QWidget *parent) : // w3stubserver, on dealloc, deletes m_qwebConnector m_qwebConnector = new QWebThreeConnector(); // owned by WebThreeStubServer - m_server.reset(new WebThreeStubServer(m_qwebConnector, *web3(), keysAsVector(m_myKeys))); + m_server.reset(new OurWebThreeStubServer(m_qwebConnector, *web3(), keysAsVector(m_myKeys))); + connect(&*m_server, SIGNAL(onNewId(QString)), SLOT(addNewId(QString))); m_server->setIdentities(keysAsVector(owned())); m_server->StartListening(); @@ -205,12 +207,28 @@ Main::~Main() writeSettings(); } +void Main::on_newIdentity_triggered() +{ + KeyPair kp = KeyPair::create(); + m_myIdentities.append(kp); + m_server->setIdentities(keysAsVector(owned())); + refreshWhisper(); +} + +void Main::refreshWhisper() +{ + ui->shhFrom->clear(); + for (auto i: m_server->ids()) + ui->shhFrom->addItem(QString::fromStdString(toHex(i.first.ref()))); +} + void Main::addNewId(QString _ids) { Secret _id = jsToSecret(_ids.toStdString()); KeyPair kp(_id); m_myIdentities.push_back(kp); m_server->setIdentities(keysAsVector(owned())); + refreshWhisper(); } dev::p2p::NetworkPreferences Main::netPrefs() const @@ -1243,6 +1261,13 @@ void Main::on_blocks_currentItemChanged() s << "
Log Bloom: " << info.logBloom << ""; s << "
Transactions: " << block[1].itemCount() << " @" << info.transactionsRoot << ""; s << "
Uncles: " << block[2].itemCount() << " @" << info.sha3Uncles << ""; + for (auto u: block[2]) + { + BlockInfo uncle = BlockInfo::fromHeader(u.data()); + s << "
 Hash: " << uncle.hash << ""; + s << "
 Parent: " << uncle.parentHash << ""; + s << "
 Number: " << uncle.number << ""; + } if (info.parentHash) s << "
Pre: " << BlockInfo(ethereum()->blockChain().block(info.parentHash)).stateRoot << ""; else @@ -1268,7 +1293,7 @@ void Main::on_blocks_currentItemChanged() s << "   #" << tx.nonce() << ""; s << "
Gas price: " << formatBalance(tx.gasPrice()) << ""; s << "
Gas: " << tx.gas() << ""; - s << "
V: " << hex << nouppercase << (int)tx.signature().v << ""; + s << "
V: " << hex << nouppercase << (int)tx.signature().v << " + 27"; s << "
R: " << hex << nouppercase << tx.signature().r << ""; s << "
S: " << hex << nouppercase << tx.signature().s << ""; s << "
Msg: " << tx.sha3(eth::WithoutSignature) << ""; @@ -2169,20 +2194,6 @@ void Main::on_post_clicked() whisper()->inject(m.seal(from, topicFromText(ui->shhTopic->toPlainText()), ui->shhTtl->value(), ui->shhWork->value())); } -void Main::on_newIdentity_triggered() -{ - KeyPair kp = KeyPair::create(); - m_myIdentities.append(kp); - m_server->setIdentities(keysAsVector(owned())); -} - -void Main::refreshWhisper() -{ - ui->shhFrom->clear(); - for (auto i: m_server ->ids()) - ui->shhFrom->addItem(QString::fromStdString(toHex(i.first.ref()))); -} - void Main::refreshWhispers() { ui->whispers->clear(); diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h index e62afb497..57f9c5ebd 100644 --- a/alethzero/MainWin.h +++ b/alethzero/MainWin.h @@ -47,7 +47,7 @@ class MessageFilter; }} class QQuickView; -class WebThreeStubServer; +class OurWebThreeStubServer; struct WorldState { @@ -256,6 +256,6 @@ private: bool m_logChanged = true; QWebThreeConnector* m_qwebConnector; - std::unique_ptr m_server; + std::unique_ptr m_server; QWebThree* m_qweb = nullptr; }; diff --git a/alethzero/OurWebThreeStubServer.cpp b/alethzero/OurWebThreeStubServer.cpp new file mode 100644 index 000000000..ca1b77649 --- /dev/null +++ b/alethzero/OurWebThreeStubServer.cpp @@ -0,0 +1,36 @@ +/* + 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 . +*/ +/** @file OurWebThreeStubServer.h + * @author Gav Wood + * @date 2014 + */ + +#include "OurWebThreeStubServer.h" +using namespace std; +using namespace dev; +using namespace dev::eth; + +OurWebThreeStubServer::OurWebThreeStubServer(jsonrpc::AbstractServerConnector* _conn, dev::WebThreeDirect& _web3, std::vector const& _accounts): + WebThreeStubServer(_conn, _web3, _accounts) +{} + +std::string OurWebThreeStubServer::newIdentity() +{ + dev::KeyPair kp = dev::KeyPair::create(); + emit onNewId(QString::fromStdString(toJS(kp.sec()))); + return toJS(kp.pub()); +} diff --git a/alethzero/OurWebThreeStubServer.h b/alethzero/OurWebThreeStubServer.h new file mode 100644 index 000000000..be06da62d --- /dev/null +++ b/alethzero/OurWebThreeStubServer.h @@ -0,0 +1,38 @@ +/* + 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 . +*/ +/** @file OurWebThreeStubServer.cpp + * @author Gav Wood + * @date 2014 + */ + +#include +#include +#include +#include + +class OurWebThreeStubServer: public QObject, public WebThreeStubServer +{ + Q_OBJECT + +public: + OurWebThreeStubServer(jsonrpc::AbstractServerConnector* _conn, dev::WebThreeDirect& _web3, std::vector const& _accounts); + + virtual std::string newIdentity() override; + +signals: + void onNewId(QString _s); +}; diff --git a/libdevcore/CommonJS.cpp b/libdevcore/CommonJS.cpp index d362f66ab..96f4b1896 100644 --- a/libdevcore/CommonJS.cpp +++ b/libdevcore/CommonJS.cpp @@ -35,8 +35,7 @@ bytes jsToBytes(std::string const& _s) // Decimal return toCompactBigEndian(bigint(_s)); else - // Binary - return asBytes(_s); + return bytes(); } std::string jsPadded(std::string const& _s, unsigned _l, unsigned _r) diff --git a/libethereum/State.cpp b/libethereum/State.cpp index 2e52187c6..4cfe66cc1 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -60,6 +60,7 @@ void ecrecoverCode(bytesConstRef _in, bytesRef _out) if (secp256k1_ecdsa_recover_compact(in.hash.data(), 32, in.r.data(), pubkey, &pubkeylen, 0, (int)(u256)in.v - 27)) ret = dev::sha3(bytesConstRef(&(pubkey[1]), 64)); + memset(ret.data(), 0, 12); memcpy(_out.data(), &ret, min(_out.size(), sizeof(ret))); } diff --git a/libjsqrc/main.js b/libjsqrc/main.js index 3e0a62c40..821de6382 100644 --- a/libjsqrc/main.js +++ b/libjsqrc/main.js @@ -217,6 +217,8 @@ // Find termination var str = ""; var i = 0, l = hex.length; + if (hex.substring(0, 2) == '0x') + i = 2; for(; i < l; i+=2) { var code = hex.charCodeAt(i) if(code == 0) { @@ -238,7 +240,7 @@ var hex = this.toHex(str); while(hex.length < pad*2) hex += "00"; - return hex + return "0x" + hex }, eth: { diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index 026aef975..44cf39291 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -283,14 +283,6 @@ void WhileStatement::checkTypeRequirements() m_body->checkTypeRequirements(); } -void Continue::checkTypeRequirements() -{ -} - -void Break::checkTypeRequirements() -{ -} - void Return::checkTypeRequirements() { if (!m_expression) @@ -326,8 +318,6 @@ void VariableDefinition::checkTypeRequirements() void Assignment::checkTypeRequirements() { - //@todo lefthandside actually has to be assignable - // add a feature to the type system to check that m_leftHandSide->checkTypeRequirements(); if (!m_leftHandSide->isLvalue()) BOOST_THROW_EXCEPTION(createTypeError("Expression has to be an lvalue.")); @@ -366,8 +356,8 @@ void UnaryOperation::checkTypeRequirements() void BinaryOperation::checkTypeRequirements() { - m_right->checkTypeRequirements(); m_left->checkTypeRequirements(); + m_right->checkTypeRequirements(); if (m_right->getType()->isImplicitlyConvertibleTo(*m_left->getType())) m_commonType = m_left->getType(); else if (m_left->getType()->isImplicitlyConvertibleTo(*m_right->getType())) @@ -446,14 +436,6 @@ void Identifier::checkTypeRequirements() if (asserts(m_referencedDeclaration)) BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Identifier not resolved.")); - //@todo these dynamic casts here are not really nice... - // is i useful to have an AST visitor here? - // or can this already be done in NameAndTypeResolver? - // the only problem we get there is that in - // var x; - // x = 2; - // var y = x; - // the type of x is not yet determined. VariableDeclaration* variable = dynamic_cast(m_referencedDeclaration); if (variable) { diff --git a/libsolidity/AST.h b/libsolidity/AST.h index f42ff47d0..793ce863f 100644 --- a/libsolidity/AST.h +++ b/libsolidity/AST.h @@ -390,7 +390,7 @@ class Continue: public Statement public: Continue(Location const& _location): Statement(_location) {} virtual void accept(ASTVisitor& _visitor) override; - virtual void checkTypeRequirements() override; + virtual void checkTypeRequirements() override {} }; class Break: public Statement @@ -398,7 +398,7 @@ class Break: public Statement public: Break(Location const& _location): Statement(_location) {} virtual void accept(ASTVisitor& _visitor) override; - virtual void checkTypeRequirements() override; + virtual void checkTypeRequirements() override {} }; class Return: public Statement diff --git a/libsolidity/Compiler.cpp b/libsolidity/Compiler.cpp index 654eceadb..d05552b9e 100644 --- a/libsolidity/Compiler.cpp +++ b/libsolidity/Compiler.cpp @@ -252,17 +252,15 @@ bool Compiler::visit(WhileStatement& _whileStatement) bool Compiler::visit(Continue&) { - if (asserts(!m_continueTags.empty())) - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Jump tag not available for \"continue\".")); - m_context.appendJumpTo(m_continueTags.back()); + if (!m_continueTags.empty()) + m_context.appendJumpTo(m_continueTags.back()); return false; } bool Compiler::visit(Break&) { - if (asserts(!m_breakTags.empty())) - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Jump tag not available for \"break\".")); - m_context.appendJumpTo(m_breakTags.back()); + if (!m_breakTags.empty()) + m_context.appendJumpTo(m_breakTags.back()); return false; } diff --git a/libweb3jsonrpc/WebThreeStubServer.cpp b/libweb3jsonrpc/WebThreeStubServer.cpp index 89d45f4e0..12a18d938 100644 --- a/libweb3jsonrpc/WebThreeStubServer.cpp +++ b/libweb3jsonrpc/WebThreeStubServer.cpp @@ -211,7 +211,7 @@ static shh::Message toMessage(Json::Value const& _json) if (!_json["to"].empty()) ret.setTo(jsToPublic(_json["to"].asString())); if (!_json["payload"].empty()) - ret.setPayload(asBytes(_json["payload"].asString())); + ret.setPayload(jsToBytes(_json["payload"].asString())); return ret; } @@ -228,10 +228,10 @@ static shh::Envelope toSealed(Json::Value const& _json, shh::Message const& _m, if (!_json["topic"].empty()) { if (_json["topic"].isString()) - bt.shift(asBytes(jsPadded(_json["topic"].asString(), 32))); + bt.shift(jsToBytes(_json["topic"].asString())); else if (_json["topic"].isArray()) for (auto i: _json["topic"]) - bt.shift(asBytes(jsPadded(i.asString(), 32))); + bt.shift(jsToBytes(i.asString())); } return _m.seal(_from, bt, ttl, workToProve); } @@ -247,12 +247,12 @@ static pair toWatch(Json::Value const& _json) if (!_json["topic"].empty()) { if (_json["topic"].isString()) - bt.shift(asBytes(jsPadded(_json["topic"].asString(), 32))); + bt.shift(jsToBytes(_json["topic"].asString())); else if (_json["topic"].isArray()) for (auto i: _json["topic"]) { if (i.isString()) - bt.shift(asBytes(jsPadded(i.asString(), 32))); + bt.shift(jsToBytes(i.asString())); else bt.shift(); } @@ -372,10 +372,10 @@ static TransactionSkeleton toTransaction(Json::Value const& _json) ret.data = jsToBytes(_json["code"].asString()); else if (_json["data"].isArray()) for (auto i: _json["data"]) - dev::operator +=(ret.data, asBytes(jsPadded(i.asString(), 32))); + dev::operator +=(ret.data, jsToBytes(jsPadded(i.asString(), 32))); else if (_json["code"].isArray()) for (auto i: _json["code"]) - dev::operator +=(ret.data, asBytes(jsPadded(i.asString(), 32))); + dev::operator +=(ret.data, jsToBytes(jsPadded(i.asString(), 32))); else if (_json["dataclose"].isArray()) for (auto i: _json["dataclose"]) dev::operator +=(ret.data, jsToBytes(i.asString())); @@ -509,6 +509,7 @@ std::string WebThreeStubServer::newGroup(std::string const& _id, std::string con std::string WebThreeStubServer::newIdentity() { + cnote << this << m_ids; KeyPair kp = KeyPair::create(); m_ids[kp.pub()] = kp.secret(); return toJS(kp.pub()); @@ -531,6 +532,7 @@ int WebThreeStubServer::peerCount() bool WebThreeStubServer::post(Json::Value const& _json) { + cnote << this << m_ids; shh::Message m = toMessage(_json); Secret from; diff --git a/stdserv.js b/stdserv.js index 68d33ddd9..55ae90d86 100644 --- a/stdserv.js +++ b/stdserv.js @@ -55,6 +55,14 @@ eth.transact({ 'code': nameRegCode }, function(a) { nameReg = a; }); env.note('Register NameReg...') eth.transact({ 'to': config, 'data': ['0', nameReg] }); +var nameRegJeff; + +env.note('Create NameRegJeff...') +eth.transact({ 'code': nameRegCode }, function(a) { nameRegJeff = a; }); + +env.note('Register NameRegJeff...') +eth.transact({ 'to': config, 'data': ['4', nameReg] }); + var dnsRegCode = '0x60006000546000600053602001546000600053604001546020604060206020600073661005d2720d855f1d9976f88bb10c1a3398c77f6103e8f17f7265676973746572000000000000000000000000000000000000000000000000600053606001600060200201547f446e735265670000000000000000000000000000000000000000000000000000600053606001600160200201546000600060006000604060606000600053604001536103e8f1327f6f776e65720000000000000000000000000000000000000000000000000000005761011663000000e46000396101166000f20060006000547f72656769737465720000000000000000000000000000000000000000000000006000602002350e0f630000006d596000600160200235560e0f630000006c59600032560e0f0f6300000057596000325657600260200235600160200235576001602002353257007f64657265676973746572000000000000000000000000000000000000000000006000602002350e0f63000000b95960016020023532560e0f63000000b959600032576000600160200235577f6b696c6c000000000000000000000000000000000000000000000000000000006000602002350e0f630000011559327f6f776e6572000000000000000000000000000000000000000000000000000000560e0f63000001155932ff00'; var dnsReg; diff --git a/test/solidityEndToEndTest.cpp b/test/solidityEndToEndTest.cpp index b28b8499a..116310aed 100644 --- a/test/solidityEndToEndTest.cpp +++ b/test/solidityEndToEndTest.cpp @@ -151,6 +151,55 @@ BOOST_AUTO_TEST_CASE(while_loop) BOOST_CHECK(framework.callFunction(0, u256(4)) == toBigEndian(u256(24))); } +BOOST_AUTO_TEST_CASE(break_outside_loop) +{ + // break and continue outside loops should be simply ignored + char const* sourceCode = "contract test {\n" + " function f(uint x) returns(uint y) {\n" + " break; continue; return 2;\n" + " }\n" + "}\n"; + ExecutionFramework framework; + framework.compileAndRun(sourceCode); + BOOST_CHECK(framework.callFunction(0, u256(0)) == toBigEndian(u256(2))); +} + +BOOST_AUTO_TEST_CASE(nested_loops) +{ + // tests that break and continue statements in nested loops jump to the correct place + char const* sourceCode = "contract test {\n" + " function f(uint x) returns(uint y) {\n" + " while (x > 1) {\n" + " if (x == 10) break;\n" + " while (x > 5) {\n" + " if (x == 8) break;\n" + " x--;\n" + " if (x == 6) continue;\n" + " return x;\n" + " }\n" + " x--;\n" + " if (x == 3) continue;\n" + " break;\n" + " }\n" + " return x;\n" + " }\n" + "}\n"; + ExecutionFramework framework; + framework.compileAndRun(sourceCode); + BOOST_CHECK(framework.callFunction(0, u256(0)) == toBigEndian(u256(0))); + BOOST_CHECK(framework.callFunction(0, u256(1)) == toBigEndian(u256(1))); + BOOST_CHECK(framework.callFunction(0, u256(2)) == toBigEndian(u256(1))); + BOOST_CHECK(framework.callFunction(0, u256(3)) == toBigEndian(u256(2))); + BOOST_CHECK(framework.callFunction(0, u256(4)) == toBigEndian(u256(2))); + BOOST_CHECK(framework.callFunction(0, u256(5)) == toBigEndian(u256(4))); + BOOST_CHECK(framework.callFunction(0, u256(6)) == toBigEndian(u256(5))); + BOOST_CHECK(framework.callFunction(0, u256(7)) == toBigEndian(u256(5))); + BOOST_CHECK(framework.callFunction(0, u256(8)) == toBigEndian(u256(7))); + BOOST_CHECK(framework.callFunction(0, u256(9)) == toBigEndian(u256(8))); + BOOST_CHECK(framework.callFunction(0, u256(10)) == toBigEndian(u256(10))); + BOOST_CHECK(framework.callFunction(0, u256(11)) == toBigEndian(u256(10))); +} + BOOST_AUTO_TEST_CASE(calling_other_functions) { // note that the index of a function is its index in the sorted sequence of functions