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