Browse Source

Merge remote-tracking branch 'upstream/develop' into NewStateTests

Conflicts:
	test/state.cpp
	test/tmpFiller.json
cl-refactor
Christoph Jentzsch 10 years ago
parent
commit
f57e6b1e35
  1. 4
      alethzero/MainWin.cpp
  2. 6
      libdevcore/RLP.h
  3. 2
      libevm/ExtVMFace.cpp
  4. 2
      libevm/ExtVMFace.h
  5. 4
      libevmcore/Instruction.cpp
  6. 44
      libjsqrc/main.js
  7. 8
      libjsqrc/qt.js
  8. 1
      libqethereum/QEthereum.cpp
  9. 51
      libsolidity/ExpressionCompiler.cpp
  10. 4
      libsolidity/Types.cpp
  11. 3
      libweb3jsonrpc/WebThreeStubServer.cpp
  12. 35
      libwhisper/Common.cpp
  13. 8
      libwhisper/Common.h
  14. 7
      libwhisper/Interface.cpp
  15. 2
      libwhisper/Interface.h
  16. 4
      libwhisper/Message.cpp
  17. 13
      libwhisper/Message.h
  18. 7
      libwhisper/WhisperHost.cpp
  19. 2
      libwhisper/WhisperHost.h
  20. 4
      libwhisper/WhisperPeer.cpp
  21. 2
      libwhisper/WhisperPeer.h
  22. 1
      test/TestHelper.h
  23. 2
      test/createRandomTest.cpp
  24. 2
      test/solidityCompiler.cpp
  25. 73
      test/solidityExpressionCompiler.cpp
  26. 8
      test/state.cpp
  27. 35
      test/tmpFiller.json
  28. 2
      test/vm.cpp

4
alethzero/MainWin.cpp

@ -610,6 +610,7 @@ void Main::readSettings(bool _skipGeometry)
} }
} }
ethereum()->setAddress(m_myKeys.back().address()); ethereum()->setAddress(m_myKeys.back().address());
m_server->setAccounts(keysAsVector(m_myKeys));
} }
{ {
@ -1821,6 +1822,7 @@ void Main::on_send_clicked()
void Main::keysChanged() void Main::keysChanged()
{ {
onBalancesChange(); onBalancesChange();
m_server->setAccounts(keysAsVector(m_myKeys));
} }
void Main::on_debug_clicked() void Main::on_debug_clicked()
@ -2218,7 +2220,7 @@ void Main::refreshWhispers()
time_t ex = e.expiry(); time_t ex = e.expiry();
QString t(ctime(&ex)); QString t(ctime(&ex));
t.chop(1); t.chop(1);
QString item = QString("[%1 - %2s] *%3 %5 %4").arg(t).arg(e.ttl()).arg(e.workProved()).arg(toString(e.topic()).c_str()).arg(msg); QString item = QString("[%1 - %2s] *%3 %5 %4").arg(t).arg(e.ttl()).arg(e.workProved()).arg(toString(e.topics()).c_str()).arg(msg);
ui->whispers->addItem(item); ui->whispers->addItem(item);
} }
} }

6
libdevcore/RLP.h

@ -159,7 +159,11 @@ public:
/// Best-effort conversion operators. /// Best-effort conversion operators.
explicit operator std::string() const { return toString(); } explicit operator std::string() const { return toString(); }
explicit operator RLPs() const { return toList(); } explicit operator RLPs() const { return toList(); }
explicit operator byte() const { return toInt<byte>(); } explicit operator uint8_t() const { return toInt<uint8_t>(); }
explicit operator uint16_t() const { return toInt<uint16_t>(); }
explicit operator uint32_t() const { return toInt<uint32_t>(); }
explicit operator uint64_t() const { return toInt<uint64_t>(); }
explicit operator u160() const { return toInt<u160>(); }
explicit operator u256() const { return toInt<u256>(); } explicit operator u256() const { return toInt<u256>(); }
explicit operator bigint() const { return toInt<bigint>(); } explicit operator bigint() const { return toInt<bigint>(); }
template <unsigned _N> explicit operator FixedHash<_N>() const { return toHash<FixedHash<_N>>(); } template <unsigned _N> explicit operator FixedHash<_N>() const { return toHash<FixedHash<_N>>(); }

2
libevm/ExtVMFace.cpp

@ -25,7 +25,7 @@ using namespace std;
using namespace dev; using namespace dev;
using namespace dev::eth; using namespace dev::eth;
ExtVMFace::ExtVMFace(Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytes _code, BlockInfo const& _previousBlock, BlockInfo const& _currentBlock, unsigned _depth): ExtVMFace::ExtVMFace(Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytes const& _code, BlockInfo const& _previousBlock, BlockInfo const& _currentBlock, unsigned _depth):
myAddress(_myAddress), myAddress(_myAddress),
caller(_caller), caller(_caller),
origin(_origin), origin(_origin),

2
libevm/ExtVMFace.h

@ -104,7 +104,7 @@ public:
ExtVMFace() = default; ExtVMFace() = default;
/// Full constructor. /// Full constructor.
ExtVMFace(Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytes _code, BlockInfo const& _previousBlock, BlockInfo const& _currentBlock, unsigned _depth); ExtVMFace(Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytes const& _code, BlockInfo const& _previousBlock, BlockInfo const& _currentBlock, unsigned _depth);
virtual ~ExtVMFace() = default; virtual ~ExtVMFace() = default;

4
libevmcore/Instruction.cpp

@ -172,13 +172,13 @@ static const std::map<Instruction, InstructionInfo> c_instructionInfo =
{ Instruction::MOD, { "MOD", 0, 2, 1 } }, { Instruction::MOD, { "MOD", 0, 2, 1 } },
{ Instruction::SMOD, { "SMOD", 0, 2, 1 } }, { Instruction::SMOD, { "SMOD", 0, 2, 1 } },
{ Instruction::EXP, { "EXP", 0, 2, 1 } }, { Instruction::EXP, { "EXP", 0, 2, 1 } },
{ Instruction::NOT, { "BNOT", 0, 1, 1 } }, { Instruction::NOT, { "NOT", 0, 1, 1 } },
{ Instruction::LT, { "LT", 0, 2, 1 } }, { Instruction::LT, { "LT", 0, 2, 1 } },
{ Instruction::GT, { "GT", 0, 2, 1 } }, { Instruction::GT, { "GT", 0, 2, 1 } },
{ Instruction::SLT, { "SLT", 0, 2, 1 } }, { Instruction::SLT, { "SLT", 0, 2, 1 } },
{ Instruction::SGT, { "SGT", 0, 2, 1 } }, { Instruction::SGT, { "SGT", 0, 2, 1 } },
{ Instruction::EQ, { "EQ", 0, 2, 1 } }, { Instruction::EQ, { "EQ", 0, 2, 1 } },
{ Instruction::ISZERO, { "NOT", 0, 1, 1 } }, { Instruction::ISZERO, { "ISZERO", 0, 1, 1 } },
{ Instruction::AND, { "AND", 0, 2, 1 } }, { Instruction::AND, { "AND", 0, 2, 1 } },
{ Instruction::OR, { "OR", 0, 2, 1 } }, { Instruction::OR, { "OR", 0, 2, 1 } },
{ Instruction::XOR, { "XOR", 0, 2, 1 } }, { Instruction::XOR, { "XOR", 0, 2, 1 } },

44
libjsqrc/main.js

@ -2,19 +2,19 @@
This file is part of ethereum.js. This file is part of ethereum.js.
ethereum.js is free software: you can redistribute it and/or modify ethereum.js is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
ethereum.js is distributed in the hope that it will be useful, ethereum.js is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with ethereum.js. If not, see <http://www.gnu.org/licenses/>. along with ethereum.js. If not, see <http://www.gnu.org/licenses/>.
*/ */
/** @file ethereum.js /** @file main.js
* @authors: * @authors:
* Marek Kotewicz <marek@ethdev.com> * Marek Kotewicz <marek@ethdev.com>
* @date 2014 * @date 2014
@ -153,15 +153,15 @@
return {call: call, args: args}; return {call: call, args: args};
}).then(function (request) { }).then(function (request) {
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
web3.provider.send(request, function (result) { web3.provider.send(request, function (err, result) {
if (result || typeof result === "boolean") { if (!err) {
resolve(result); resolve(result);
return; return;
} }
reject(result); reject(err);
}); });
}); });
}).catch(function( err) { }).catch(function(err) {
console.error(err); console.error(err);
}); });
}; };
@ -173,8 +173,12 @@
var proto = {}; var proto = {};
proto.get = function () { proto.get = function () {
return new Promise(function(resolve, reject) { return new Promise(function(resolve, reject) {
web3.provider.send({call: property.getter}, function(result) { web3.provider.send({call: property.getter}, function(err, result) {
resolve(result); if (!err) {
resolve(result);
return;
}
reject(err);
}); });
}); });
}; };
@ -182,12 +186,12 @@
proto.set = function (val) { proto.set = function (val) {
return flattenPromise([val]).then(function (args) { return flattenPromise([val]).then(function (args) {
return new Promise(function (resolve) { return new Promise(function (resolve) {
web3.provider.send({call: property.setter, args: args}, function (result) { web3.provider.send({call: property.setter, args: args}, function (err, result) {
if (result) { if (!err) {
resolve(result); resolve(result);
} else { return;
reject(result);
} }
reject(err);
}); });
}); });
}).catch(function (err) { }).catch(function (err) {
@ -218,7 +222,7 @@
var str = ""; var str = "";
var i = 0, l = hex.length; var i = 0, l = hex.length;
if (hex.substring(0, 2) == '0x') if (hex.substring(0, 2) == '0x')
i = 2; i = 2;
for(; i < l; i+=2) { for(; i < l; i+=2) {
var code = hex.charCodeAt(i) var code = hex.charCodeAt(i)
if(code == 0) { if(code == 0) {
@ -240,7 +244,7 @@
var hex = this.toHex(str); var hex = this.toHex(str);
while(hex.length < pad*2) while(hex.length < pad*2)
hex += "00"; hex += "00";
return "0x" + hex return "0x" + hex;
}, },
eth: { eth: {
@ -410,8 +414,10 @@
}; };
Filter.prototype.trigger = function(messages) { Filter.prototype.trigger = function(messages) {
for(var i = 0; i < this.callbacks.length; i++) { if (!(messages instanceof Array) || messages.length) {
this.callbacks[i].call(this, messages); for(var i = 0; i < this.callbacks.length; i++) {
this.callbacks[i].call(this, messages);
}
} }
}; };
@ -440,7 +446,7 @@
if(data._id) { if(data._id) {
var cb = web3._callbacks[data._id]; var cb = web3._callbacks[data._id];
if (cb) { if (cb) {
cb.call(this, data.data) cb.call(this, data.error, data.data);
delete web3._callbacks[data._id]; delete web3._callbacks[data._id];
} }
} }

8
libjsqrc/qt.js

@ -2,19 +2,19 @@
This file is part of ethereum.js. This file is part of ethereum.js.
ethereum.js is free software: you can redistribute it and/or modify ethereum.js is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
ethereum.js is distributed in the hope that it will be useful, ethereum.js is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with ethereum.js. If not, see <http://www.gnu.org/licenses/>. along with ethereum.js. If not, see <http://www.gnu.org/licenses/>.
*/ */
/** @file ethereum.js /** @file qt.js
* @authors: * @authors:
* Marek Kotewicz <marek@ethdev.com> * Marek Kotewicz <marek@ethdev.com>
* @date 2014 * @date 2014

1
libqethereum/QEthereum.cpp

@ -120,6 +120,7 @@ static QString formatOutput(QJsonObject const& _object)
QJsonObject res; QJsonObject res;
res["_id"] = _object["id"]; res["_id"] = _object["id"];
res["data"] = _object["result"]; res["data"] = _object["result"];
res["error"] = _object["error"];
return QString::fromUtf8(QJsonDocument(res).toJson()); return QString::fromUtf8(QJsonDocument(res).toJson());
} }

51
libsolidity/ExpressionCompiler.cpp

@ -48,21 +48,15 @@ bool ExpressionCompiler::visit(Assignment& _assignment)
{ {
m_currentLValue = nullptr; m_currentLValue = nullptr;
Expression& rightHandSide = _assignment.getRightHandSide(); _assignment.getRightHandSide().accept(*this);
rightHandSide.accept(*this); appendTypeConversion(*_assignment.getRightHandSide().getType(), *_assignment.getType());
Type const& resultType = *_assignment.getType();
appendTypeConversion(*rightHandSide.getType(), resultType);
_assignment.getLeftHandSide().accept(*this); _assignment.getLeftHandSide().accept(*this);
Token::Value op = _assignment.getAssignmentOperator(); Token::Value op = _assignment.getAssignmentOperator();
if (op != Token::ASSIGN) if (op != Token::ASSIGN) // compound assignment
{ appendOrdinaryBinaryOperatorCode(Token::AssignmentToBinaryOp(op), *_assignment.getType());
// compound assignment
m_context << eth::Instruction::SWAP1;
appendOrdinaryBinaryOperatorCode(Token::AssignmentToBinaryOp(op), resultType);
}
else else
m_context << eth::Instruction::POP; //@todo do not retrieve the value in the first place m_context << eth::Instruction::POP;
storeInLValue(_assignment); storeInLValue(_assignment);
return false; return false;
@ -123,11 +117,8 @@ bool ExpressionCompiler::visit(BinaryOperation& _binaryOperation)
Type const& commonType = _binaryOperation.getCommonType(); Type const& commonType = _binaryOperation.getCommonType();
Token::Value const op = _binaryOperation.getOperator(); Token::Value const op = _binaryOperation.getOperator();
if (op == Token::AND || op == Token::OR) if (op == Token::AND || op == Token::OR) // special case: short-circuiting
{
// special case: short-circuiting
appendAndOrOperatorCode(_binaryOperation); appendAndOrOperatorCode(_binaryOperation);
}
else else
{ {
bool cleanupNeeded = false; bool cleanupNeeded = false;
@ -135,10 +126,10 @@ bool ExpressionCompiler::visit(BinaryOperation& _binaryOperation)
if (Token::isCompareOp(op) || op == Token::DIV || op == Token::MOD) if (Token::isCompareOp(op) || op == Token::DIV || op == Token::MOD)
cleanupNeeded = true; cleanupNeeded = true;
leftExpression.accept(*this);
appendTypeConversion(*leftExpression.getType(), commonType, cleanupNeeded);
rightExpression.accept(*this); rightExpression.accept(*this);
appendTypeConversion(*rightExpression.getType(), commonType, cleanupNeeded); appendTypeConversion(*rightExpression.getType(), commonType, cleanupNeeded);
leftExpression.accept(*this);
appendTypeConversion(*leftExpression.getType(), commonType, cleanupNeeded);
if (Token::isCompareOp(op)) if (Token::isCompareOp(op))
appendCompareOperatorCode(op, commonType); appendCompareOperatorCode(op, commonType);
else else
@ -175,8 +166,7 @@ bool ExpressionCompiler::visit(FunctionCall& _functionCall)
for (unsigned i = 0; i < arguments.size(); ++i) for (unsigned i = 0; i < arguments.size(); ++i)
{ {
arguments[i]->accept(*this); arguments[i]->accept(*this);
appendTypeConversion(*arguments[i]->getType(), appendTypeConversion(*arguments[i]->getType(), *function.getParameters()[i]->getType());
*function.getParameters()[i]->getType());
} }
m_context.appendJumpTo(m_context.getFunctionEntryLabel(function)); m_context.appendJumpTo(m_context.getFunctionEntryLabel(function));
@ -267,23 +257,21 @@ void ExpressionCompiler::appendCompareOperatorCode(Token::Value _operator, Type
IntegerType const& type = dynamic_cast<IntegerType const&>(_type); IntegerType const& type = dynamic_cast<IntegerType const&>(_type);
bool const isSigned = type.isSigned(); bool const isSigned = type.isSigned();
// note that EVM opcodes compare like "stack[0] < stack[1]",
// but our left value is at stack[1], so everyhing is reversed.
switch (_operator) switch (_operator)
{ {
case Token::GTE: case Token::GTE:
m_context << (isSigned ? eth::Instruction::SGT : eth::Instruction::GT) m_context << (isSigned ? eth::Instruction::SLT : eth::Instruction::LT)
<< eth::Instruction::ISZERO; << eth::Instruction::ISZERO;
break; break;
case Token::LTE: case Token::LTE:
m_context << (isSigned ? eth::Instruction::SLT : eth::Instruction::LT) m_context << (isSigned ? eth::Instruction::SGT : eth::Instruction::GT)
<< eth::Instruction::ISZERO; << eth::Instruction::ISZERO;
break; break;
case Token::GT: case Token::GT:
m_context << (isSigned ? eth::Instruction::SLT : eth::Instruction::LT); m_context << (isSigned ? eth::Instruction::SGT : eth::Instruction::GT);
break; break;
case Token::LT: case Token::LT:
m_context << (isSigned ? eth::Instruction::SGT : eth::Instruction::GT); m_context << (isSigned ? eth::Instruction::SLT : eth::Instruction::LT);
break; break;
default: default:
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown comparison operator.")); BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown comparison operator."));
@ -314,16 +302,16 @@ void ExpressionCompiler::appendArithmeticOperatorCode(Token::Value _operator, Ty
m_context << eth::Instruction::ADD; m_context << eth::Instruction::ADD;
break; break;
case Token::SUB: case Token::SUB:
m_context << eth::Instruction::SWAP1 << eth::Instruction::SUB; m_context << eth::Instruction::SUB;
break; break;
case Token::MUL: case Token::MUL:
m_context << eth::Instruction::MUL; m_context << eth::Instruction::MUL;
break; break;
case Token::DIV: case Token::DIV:
m_context << eth::Instruction::SWAP1 << (isSigned ? eth::Instruction::SDIV : eth::Instruction::DIV); m_context << (isSigned ? eth::Instruction::SDIV : eth::Instruction::DIV);
break; break;
case Token::MOD: case Token::MOD:
m_context << eth::Instruction::SWAP1 << (isSigned ? eth::Instruction::SMOD : eth::Instruction::MOD); m_context << (isSigned ? eth::Instruction::SMOD : eth::Instruction::MOD);
break; break;
default: default:
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown arithmetic operator.")); BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown arithmetic operator."));
@ -364,10 +352,9 @@ void ExpressionCompiler::appendShiftOperatorCode(Token::Value _operator)
void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type const& _targetType, bool _cleanupNeeded) void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type const& _targetType, bool _cleanupNeeded)
{ {
// If the type of one of the operands is extended, we need to remove all // For a type extension, we need to remove all higher-order bits that we might have ignored in
// higher-order bits that we might have ignored in previous operations. // previous operations.
// @todo: store in the AST whether the operand might have "dirty" higher // @todo: store in the AST whether the operand might have "dirty" higher order bits
// order bits
if (_typeOnStack == _targetType && !_cleanupNeeded) if (_typeOnStack == _targetType && !_cleanupNeeded)
return; return;

4
libsolidity/Types.cpp

@ -103,8 +103,8 @@ IntegerType::IntegerType(int _bits, IntegerType::Modifier _modifier):
m_bits(_bits), m_modifier(_modifier) m_bits(_bits), m_modifier(_modifier)
{ {
if (isAddress()) if (isAddress())
_bits = 160; m_bits = 160;
if (asserts(_bits > 0 && _bits <= 256 && _bits % 8 == 0)) if (asserts(m_bits > 0 && m_bits <= 256 && m_bits % 8 == 0))
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Invalid bit number for integer type: " + dev::toString(_bits))); BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Invalid bit number for integer type: " + dev::toString(_bits)));
} }

3
libweb3jsonrpc/WebThreeStubServer.cpp

@ -268,7 +268,8 @@ static Json::Value toJson(h256 const& _h, shh::Envelope const& _e, shh::Message
res["sent"] = (int)_e.sent(); res["sent"] = (int)_e.sent();
res["ttl"] = (int)_e.ttl(); res["ttl"] = (int)_e.ttl();
res["workProved"] = (int)_e.workProved(); res["workProved"] = (int)_e.workProved();
res["topic"] = toJS(_e.topic()); for (auto const& t: _e.topics())
res["topics"].append(toJS((u256)t));
res["payload"] = toJS(_m.payload()); res["payload"] = toJS(_m.payload());
res["from"] = toJS(_m.from()); res["from"] = toJS(_m.from());
res["to"] = toJS(_m.to()); res["to"] = toJS(_m.to());

35
libwhisper/Common.cpp

@ -22,11 +22,21 @@
#include "Common.h" #include "Common.h"
#include <libdevcrypto/SHA3.h> #include <libdevcrypto/SHA3.h>
#include "Message.h"
using namespace std; using namespace std;
using namespace dev; using namespace dev;
using namespace dev::p2p; using namespace dev::p2p;
using namespace dev::shh; using namespace dev::shh;
Topic BuildTopic::toTopic() const
{
Topic ret;
ret.reserve(m_parts.size());
for (auto const& h: m_parts)
ret.push_back((TopicPart)u256(h));
return ret;
}
BuildTopic& BuildTopic::shiftBytes(bytes const& _b) BuildTopic& BuildTopic::shiftBytes(bytes const& _b)
{ {
m_parts.push_back(dev::sha3(_b)); m_parts.push_back(dev::sha3(_b));
@ -40,19 +50,32 @@ h256 TopicFilter::sha3() const
return dev::sha3(s.out()); return dev::sha3(s.out());
} }
bool TopicFilter::matches(Envelope const& _e) const
{
for (TopicMask const& t: m_topicMasks)
{
if (_e.topics().size() == t.size())
for (unsigned i = 0; i < t.size(); ++i)
if (((t[i].first ^ _e.topics()[i]) & t[i].second) != 0)
goto NEXT_TOPICMASK;
return true;
NEXT_TOPICMASK:;
}
return false;
}
TopicMask BuildTopicMask::toTopicMask() const TopicMask BuildTopicMask::toTopicMask() const
{ {
TopicMask ret; TopicMask ret;
if (m_parts.size()) ret.reserve(m_parts.size());
for (auto i = 0; i < 32; ++i) for (auto const& h: m_parts)
{ ret.push_back(make_pair((TopicPart)u256(h), h ? ~(uint32_t)0 : 0));
ret.first[i] = m_parts[i * m_parts.size() / 32][i];
ret.second[i] = m_parts[i * m_parts.size() / 32] ? 255 : 0;
}
return ret; return ret;
} }
/* /*
web3.shh.watch({}).arrived(function(m) { env.note("New message:\n"+JSON.stringify(m)); }) web3.shh.watch({}).arrived(function(m) { env.note("New message:\n"+JSON.stringify(m)); })
k = web3.shh.newIdentity() k = web3.shh.newIdentity()
web3.shh.post({from: k, topic: web3.fromAscii("test"), payload: web3.fromAscii("Hello world!")}) web3.shh.post({from: k, topic: web3.fromAscii("test"), payload: web3.fromAscii("Hello world!")})
*/ */

8
libwhisper/Common.h

@ -59,7 +59,9 @@ enum WhisperPacket
PacketCount PacketCount
}; };
using Topic = h256; using TopicPart = uint32_t;
using Topic = std::vector<TopicPart>;
class BuildTopic class BuildTopic
{ {
@ -73,7 +75,7 @@ public:
BuildTopic& shiftRaw(h256 const& _part) { m_parts.push_back(_part); return *this; } BuildTopic& shiftRaw(h256 const& _part) { m_parts.push_back(_part); return *this; }
operator Topic() const { return toTopic(); } operator Topic() const { return toTopic(); }
Topic toTopic() const { Topic ret; for (auto i = 0; i < 32; ++i) ret[i] = m_parts[i * m_parts.size() / 32][i]; return ret; } Topic toTopic() const;
protected: protected:
BuildTopic& shiftBytes(bytes const& _b); BuildTopic& shiftBytes(bytes const& _b);
@ -81,7 +83,7 @@ protected:
h256s m_parts; h256s m_parts;
}; };
using TopicMask = std::pair<Topic, Topic>; using TopicMask = std::vector<std::pair<TopicPart, TopicPart>>;
using TopicMasks = std::vector<TopicMask>; using TopicMasks = std::vector<TopicMask>;
class TopicFilter class TopicFilter

7
libwhisper/Interface.cpp

@ -34,10 +34,7 @@ using namespace dev::shh;
#endif #endif
#define clogS(X) dev::LogOutputStream<X, true>(false) << "| " << std::setw(2) << session()->socketId() << "] " #define clogS(X) dev::LogOutputStream<X, true>(false) << "| " << std::setw(2) << session()->socketId() << "] "
bool TopicFilter::matches(Envelope const& _e) const unsigned Interface::installWatch(TopicMask const& _mask)
{ {
for (TopicMask const& t: m_topicMasks) return installWatch(TopicFilter(_mask));
if (((t.first ^ _e.topic()) & t.second) == 0)
return true;
return false;
} }

2
libwhisper/Interface.h

@ -69,7 +69,7 @@ public:
virtual void inject(Envelope const& _m, WhisperPeer* _from = nullptr) = 0; virtual void inject(Envelope const& _m, WhisperPeer* _from = nullptr) = 0;
unsigned installWatch(TopicMask const& _mask) { return installWatch(TopicFilter(_mask)); } unsigned installWatch(TopicMask const& _mask);
virtual unsigned installWatch(TopicFilter const& _filter) = 0; virtual unsigned installWatch(TopicFilter const& _filter) = 0;
virtual unsigned installWatchOnId(h256 _filterId) = 0; virtual unsigned installWatchOnId(h256 _filterId) = 0;
virtual void uninstallWatch(unsigned _watchId) = 0; virtual void uninstallWatch(unsigned _watchId) = 0;

4
libwhisper/Message.cpp

@ -97,7 +97,7 @@ Message Envelope::open(Secret const& _s) const
unsigned Envelope::workProved() const unsigned Envelope::workProved() const
{ {
h256 d[2]; h256 d[2];
d[0] = sha3NoNonce(); d[0] = sha3(WithoutNonce);
d[1] = m_nonce; d[1] = m_nonce;
return dev::sha3(bytesConstRef(d[0].data(), 64)).firstBitSet(); return dev::sha3(bytesConstRef(d[0].data(), 64)).firstBitSet();
} }
@ -106,7 +106,7 @@ void Envelope::proveWork(unsigned _ms)
{ {
// PoW // PoW
h256 d[2]; h256 d[2];
d[0] = sha3NoNonce(); d[0] = sha3(WithoutNonce);
uint32_t& n = *(uint32_t*)&(d[1][28]); uint32_t& n = *(uint32_t*)&(d[1][28]);
unsigned bestBitSet = 0; unsigned bestBitSet = 0;
bytesConstRef chuck(d[0].data(), 64); bytesConstRef chuck(d[0].data(), 64);

13
libwhisper/Message.h

@ -39,6 +39,12 @@ namespace shh
class Message; class Message;
enum IncludeNonce
{
WithoutNonce = 0,
WithNonce = 1
};
class Envelope class Envelope
{ {
friend class Message; friend class Message;
@ -56,14 +62,13 @@ public:
operator bool() const { return !!m_expiry; } operator bool() const { return !!m_expiry; }
void streamRLP(RLPStream& _s, bool _withNonce) const { _s.appendList(_withNonce ? 5 : 4) << m_expiry << m_ttl << m_topic << m_data; if (_withNonce) _s << m_nonce; } 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() const { RLPStream s; streamRLP(s, true); return dev::sha3(s.out()); } h256 sha3(IncludeNonce _withNonce = WithNonce) const { RLPStream s; streamRLP(s, _withNonce); return dev::sha3(s.out()); }
h256 sha3NoNonce() const { RLPStream s; streamRLP(s, false); return dev::sha3(s.out()); }
unsigned sent() const { return m_expiry - m_ttl; } unsigned sent() const { return m_expiry - m_ttl; }
unsigned expiry() const { return m_expiry; } unsigned expiry() const { return m_expiry; }
unsigned ttl() const { return m_ttl; } unsigned ttl() const { return m_ttl; }
Topic const& topic() const { return m_topic; } Topic const& topics() const { return m_topic; }
bytes const& data() const { return m_data; } bytes const& data() const { return m_data; }
Message open(Secret const& _s = Secret()) const; Message open(Secret const& _s = Secret()) const;

7
libwhisper/WhisperHost.cpp

@ -21,6 +21,7 @@
#include "WhisperHost.h" #include "WhisperHost.h"
#include <libdevcore/CommonIO.h>
#include <libdevcore/Log.h> #include <libdevcore/Log.h>
#include <libp2p/All.h> #include <libp2p/All.h>
using namespace std; using namespace std;
@ -48,14 +49,14 @@ void WhisperHost::streamMessage(h256 _m, RLPStream& _s) const
{ {
UpgradeGuard ll(l); UpgradeGuard ll(l);
auto const& m = m_messages.at(_m); auto const& m = m_messages.at(_m);
cnote << "streamRLP: " << m.expiry() << m.ttl() << m.topic() << toHex(m.data()); cnote << "streamRLP: " << m.expiry() << m.ttl() << m.topics() << toHex(m.data());
m.streamRLP(_s, true); m.streamRLP(_s);
} }
} }
void WhisperHost::inject(Envelope const& _m, WhisperPeer* _p) void WhisperHost::inject(Envelope const& _m, WhisperPeer* _p)
{ {
cnote << "inject: " << _m.expiry() << _m.ttl() << _m.topic() << toHex(_m.data()); cnote << "inject: " << _m.expiry() << _m.ttl() << _m.topics() << toHex(_m.data());
if (_m.expiry() <= time(0)) if (_m.expiry() <= time(0))
return; return;

2
libwhisper/WhisperHost.h

@ -46,7 +46,7 @@ public:
WhisperHost(); WhisperHost();
virtual ~WhisperHost(); virtual ~WhisperHost();
unsigned protocolVersion() const { return 0; } unsigned protocolVersion() const { return 1; }
virtual void inject(Envelope const& _e, WhisperPeer* _from = nullptr) override; virtual void inject(Envelope const& _e, WhisperPeer* _from = nullptr) override;

4
libwhisper/WhisperPeer.cpp

@ -37,7 +37,7 @@ using namespace dev::shh;
WhisperPeer::WhisperPeer(Session* _s, HostCapabilityFace* _h, unsigned _i): Capability(_s, _h, _i) WhisperPeer::WhisperPeer(Session* _s, HostCapabilityFace* _h, unsigned _i): Capability(_s, _h, _i)
{ {
RLPStream s; RLPStream s;
sealAndSend(prep(s, StatusPacket, 1) << host()->protocolVersion()); sealAndSend(prep(s, StatusPacket, 1) << version());
} }
WhisperPeer::~WhisperPeer() WhisperPeer::~WhisperPeer()
@ -59,7 +59,7 @@ bool WhisperPeer::interpret(unsigned _id, RLP const& _r)
clogS(NetMessageSummary) << "Status: " << protocolVersion; clogS(NetMessageSummary) << "Status: " << protocolVersion;
if (protocolVersion != host()->protocolVersion()) if (protocolVersion != version())
disable("Invalid protocol version."); disable("Invalid protocol version.");
if (session()->id() < host()->host()->id()) if (session()->id() < host()->host()->id())

2
libwhisper/WhisperPeer.h

@ -53,7 +53,7 @@ public:
virtual ~WhisperPeer(); virtual ~WhisperPeer();
static std::string name() { return "shh"; } static std::string name() { return "shh"; }
static u256 version() { return 1; } static u256 version() { return 2; }
static unsigned messageCount() { return PacketCount; } static unsigned messageCount() { return PacketCount; }
WhisperHost* host() const; WhisperHost* host() const;

1
test/TestHelper.h

@ -57,7 +57,6 @@ public:
eth::State m_statePost; eth::State m_statePost;
eth::ExtVMFace m_environment; eth::ExtVMFace m_environment;
eth::Transaction m_transaction; eth::Transaction m_transaction;
bytes code;
private: private:
json_spirit::mObject& m_TestObject; json_spirit::mObject& m_TestObject;

2
test/createRandomTest.cpp

@ -134,7 +134,7 @@ void doMyTests(json_spirit::mValue& v)
o["pre"] = mValue(fev.exportState()); o["pre"] = mValue(fev.exportState());
fev.importExec(o["exec"].get_obj()); fev.importExec(o["exec"].get_obj());
if (!fev.code.size()) if (fev.code.empty())
{ {
fev.thisTxCode = get<3>(fev.addresses.at(fev.myAddress)); fev.thisTxCode = get<3>(fev.addresses.at(fev.myAddress));
fev.code = fev.thisTxCode; fev.code = fev.thisTxCode;

2
test/solidityCompiler.cpp

@ -119,7 +119,7 @@ BOOST_AUTO_TEST_CASE(different_argument_numbers)
byte(Instruction::JUMPDEST), // beginning of g byte(Instruction::JUMPDEST), // beginning of g
byte(Instruction::PUSH1), 0x0, byte(Instruction::PUSH1), 0x0,
byte(Instruction::DUP1), // initialized e and h byte(Instruction::DUP1), // initialized e and h
byte(Instruction::PUSH1), 0x29 + shift, // ret address byte(Instruction::PUSH1), byte(0x29 + shift), // ret address
byte(Instruction::PUSH1), 0x1, byte(Instruction::PUSH1), 0xff, byte(Instruction::AND), byte(Instruction::PUSH1), 0x1, byte(Instruction::PUSH1), 0xff, byte(Instruction::AND),
byte(Instruction::PUSH1), 0x2, byte(Instruction::PUSH1), 0xff, byte(Instruction::AND), byte(Instruction::PUSH1), 0x2, byte(Instruction::PUSH1), 0xff, byte(Instruction::AND),
byte(Instruction::PUSH1), 0x3, byte(Instruction::PUSH1), 0xff, byte(Instruction::AND), byte(Instruction::PUSH1), 0x3, byte(Instruction::PUSH1), 0xff, byte(Instruction::AND),

73
test/solidityExpressionCompiler.cpp

@ -154,10 +154,10 @@ BOOST_AUTO_TEST_CASE(comparison)
"}\n"; "}\n";
bytes code = compileFirstExpression(sourceCode); bytes code = compileFirstExpression(sourceCode);
bytes expectation({byte(eth::Instruction::PUSH2), 0x10, 0xaa, byte(eth::Instruction::PUSH2), 0xff, 0xff, byte(eth::Instruction::AND), bytes expectation({byte(eth::Instruction::PUSH1), 0x1,
byte(eth::Instruction::PUSH2), 0x11, 0xaa, byte(eth::Instruction::PUSH2), 0xff, 0xff, byte(eth::Instruction::AND), byte(eth::Instruction::PUSH2), 0x11, 0xaa, byte(eth::Instruction::PUSH2), 0xff, 0xff, byte(eth::Instruction::AND),
byte(eth::Instruction::GT), byte(eth::Instruction::PUSH2), 0x10, 0xaa, byte(eth::Instruction::PUSH2), 0xff, 0xff, byte(eth::Instruction::AND),
byte(eth::Instruction::PUSH1), 0x1, byte(eth::Instruction::LT),
byte(eth::Instruction::EQ), byte(eth::Instruction::EQ),
byte(eth::Instruction::ISZERO)}); byte(eth::Instruction::ISZERO)});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end()); BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
@ -166,7 +166,7 @@ BOOST_AUTO_TEST_CASE(comparison)
BOOST_AUTO_TEST_CASE(short_circuiting) BOOST_AUTO_TEST_CASE(short_circuiting)
{ {
char const* sourceCode = "contract test {\n" char const* sourceCode = "contract test {\n"
" function f() { var x = (10 + 8 >= 4 || 2 != 9) != true; }" " function f() { var x = true != (4 <= 8 + 10 || 9 != 2); }"
"}\n"; "}\n";
bytes code = compileFirstExpression(sourceCode); bytes code = compileFirstExpression(sourceCode);
@ -194,7 +194,7 @@ BOOST_AUTO_TEST_CASE(short_circuiting)
BOOST_AUTO_TEST_CASE(arithmetics) BOOST_AUTO_TEST_CASE(arithmetics)
{ {
char const* sourceCode = "contract test {\n" char const* sourceCode = "contract test {\n"
" function f() { var x = (1 * (2 / (3 % (4 + (5 - (6 | (7 & (8 ^ 9)))))))); }" " function f() { var x = ((((((((9 ^ 8) & 7) | 6) - 5) + 4) % 3) / 2) * 1); }"
"}\n"; "}\n";
bytes code = compileFirstExpression(sourceCode); bytes code = compileFirstExpression(sourceCode);
bytes expectation({byte(eth::Instruction::PUSH1), 0x1, bytes expectation({byte(eth::Instruction::PUSH1), 0x1,
@ -211,14 +211,11 @@ BOOST_AUTO_TEST_CASE(arithmetics)
byte(eth::Instruction::XOR), byte(eth::Instruction::XOR),
byte(eth::Instruction::AND), byte(eth::Instruction::AND),
byte(eth::Instruction::OR), byte(eth::Instruction::OR),
byte(eth::Instruction::SWAP1),
byte(eth::Instruction::SUB), byte(eth::Instruction::SUB),
byte(eth::Instruction::ADD), byte(eth::Instruction::ADD),
byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND), byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND),
byte(eth::Instruction::SWAP1),
byte(eth::Instruction::MOD), byte(eth::Instruction::MOD),
byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND), byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND),
byte(eth::Instruction::SWAP1),
byte(eth::Instruction::DIV), byte(eth::Instruction::DIV),
byte(eth::Instruction::MUL)}); byte(eth::Instruction::MUL)});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end()); BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
@ -231,11 +228,11 @@ BOOST_AUTO_TEST_CASE(unary_operators)
"}\n"; "}\n";
bytes code = compileFirstExpression(sourceCode); bytes code = compileFirstExpression(sourceCode);
bytes expectation({byte(eth::Instruction::PUSH1), 0x1, bytes expectation({byte(eth::Instruction::PUSH1), 0x2, byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND),
byte(eth::Instruction::PUSH1), 0x1,
byte(eth::Instruction::PUSH1), 0x0, byte(eth::Instruction::PUSH1), 0x0,
byte(eth::Instruction::SUB), byte(eth::Instruction::SUB),
byte(eth::Instruction::NOT), byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND), byte(eth::Instruction::NOT), byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND),
byte(eth::Instruction::PUSH1), 0x2, byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND),
byte(eth::Instruction::EQ), byte(eth::Instruction::EQ),
byte(eth::Instruction::ISZERO)}); byte(eth::Instruction::ISZERO)});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end()); BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
@ -244,7 +241,7 @@ BOOST_AUTO_TEST_CASE(unary_operators)
BOOST_AUTO_TEST_CASE(unary_inc_dec) BOOST_AUTO_TEST_CASE(unary_inc_dec)
{ {
char const* sourceCode = "contract test {\n" char const* sourceCode = "contract test {\n"
" function f(uint a) { var x = ((a++ ^ ++a) ^ a--) ^ --a; }" " function f(uint a) { var x = --a ^ (a-- ^ (++a ^ a++)); }"
"}\n"; "}\n";
bytes code = compileFirstExpression(sourceCode, {}, {{"test", "f", "a"}, {"test", "f", "x"}}); bytes code = compileFirstExpression(sourceCode, {}, {{"test", "f", "a"}, {"test", "f", "x"}});
@ -299,16 +296,15 @@ BOOST_AUTO_TEST_CASE(assignment)
bytes code = compileFirstExpression(sourceCode, {}, {{"test", "f", "a"}, {"test", "f", "b"}}); bytes code = compileFirstExpression(sourceCode, {}, {{"test", "f", "a"}, {"test", "f", "b"}});
// Stack: a, b // Stack: a, b
bytes expectation({byte(eth::Instruction::DUP1), bytes expectation({byte(eth::Instruction::PUSH1), 0x2, byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND),
byte(eth::Instruction::DUP3), byte(eth::Instruction::DUP2),
byte(eth::Instruction::SWAP1), byte(eth::Instruction::DUP4),
byte(eth::Instruction::ADD), byte(eth::Instruction::ADD),
// Stack here: a b a+b // Stack here: a b 2 a+b
byte(eth::Instruction::SWAP2), byte(eth::Instruction::SWAP3),
byte(eth::Instruction::POP), byte(eth::Instruction::POP),
byte(eth::Instruction::DUP2), byte(eth::Instruction::DUP3),
// Stack here: a+b b a+b // Stack here: a+b b 2 a+b
byte(eth::Instruction::PUSH1), 0x2, byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND),
byte(eth::Instruction::MUL)}); byte(eth::Instruction::MUL)});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end()); BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
} }
@ -323,21 +319,20 @@ BOOST_AUTO_TEST_CASE(function_call)
{{"test", "f", "a"}, {"test", "f", "b"}}); {{"test", "f", "a"}, {"test", "f", "b"}});
// Stack: a, b // Stack: a, b
bytes expectation({byte(eth::Instruction::PUSH1), 0x0d, bytes expectation({byte(eth::Instruction::PUSH1), 0x02, byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND),
byte(eth::Instruction::DUP3), byte(eth::Instruction::PUSH1), 0x12,
byte(eth::Instruction::PUSH1), 0x01, byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND), byte(eth::Instruction::PUSH1), 0x01, byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND),
byte(eth::Instruction::DUP5),
byte(eth::Instruction::ADD), byte(eth::Instruction::ADD),
// Stack here: a b <ret label> (a+1) // Stack here: a b 2 <ret label> (a+1)
byte(eth::Instruction::DUP3), byte(eth::Instruction::DUP4),
byte(eth::Instruction::PUSH1), 0x1a, byte(eth::Instruction::PUSH1), 0x19,
byte(eth::Instruction::JUMP), byte(eth::Instruction::JUMP),
byte(eth::Instruction::JUMPDEST), byte(eth::Instruction::JUMPDEST),
// Stack here: a b g(a+1, b) // Stack here: a b 2 g(a+1, b)
byte(eth::Instruction::PUSH1), 0x02, byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND),
byte(eth::Instruction::MUL), byte(eth::Instruction::MUL),
// Stack here: a b g(a+1, b)*2 // Stack here: a b g(a+1, b)*2
byte(eth::Instruction::DUP3), byte(eth::Instruction::DUP3),
byte(eth::Instruction::SWAP1),
byte(eth::Instruction::ADD), byte(eth::Instruction::ADD),
// Stack here: a b a+g(a+1, b)*2 // Stack here: a b a+g(a+1, b)*2
byte(eth::Instruction::SWAP2), byte(eth::Instruction::SWAP2),
@ -355,15 +350,15 @@ BOOST_AUTO_TEST_CASE(negative_literals_8bits)
"}\n"; "}\n";
bytes code = compileFirstExpression(sourceCode); bytes code = compileFirstExpression(sourceCode);
bytes expectation(bytes({byte(eth::Instruction::PUSH1), 0x00, bytes expectation(bytes({byte(eth::Instruction::PUSH32)}) + bytes(31, 0xff) + bytes(1, 0x80) +
byte(eth::Instruction::PUSH32)}) + bytes(32, 0xff) + bytes({byte(eth::Instruction::PUSH32)}) + bytes(31, 0xff) + bytes(1, 0x81) +
bytes({byte(eth::Instruction::ADD), bytes({byte(eth::Instruction::PUSH32)}) + bytes(32, 0xff) +
byte(eth::Instruction::PUSH32)}) + bytes(32, 0xff) + bytes({byte(eth::Instruction::PUSH32)}) + bytes(32, 0xff) +
bytes({byte(eth::Instruction::ADD), bytes({byte(eth::Instruction::PUSH1), 0x00,
byte(eth::Instruction::PUSH32)}) + bytes(31, 0xff) + bytes(1, 0x81) + byte(eth::Instruction::ADD),
bytes({byte(eth::Instruction::ADD), byte(eth::Instruction::ADD),
byte(eth::Instruction::PUSH32)}) + bytes(31, 0xff) + bytes(1, 0x80) + byte(eth::Instruction::ADD),
bytes({byte(eth::Instruction::ADD)})); byte(eth::Instruction::ADD)}));
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end()); BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
} }
@ -376,11 +371,11 @@ BOOST_AUTO_TEST_CASE(negative_literals_16bits)
"}\n"; "}\n";
bytes code = compileFirstExpression(sourceCode); bytes code = compileFirstExpression(sourceCode);
bytes expectation(bytes({byte(eth::Instruction::PUSH32)}) + bytes(32, 0xff) + bytes expectation(bytes({byte(eth::Instruction::PUSH32)}) + bytes(31, 0xff) + bytes(1, 0x7f) +
bytes({byte(eth::Instruction::PUSH32)}) + bytes(32, 0xff) +
bytes({byte(eth::Instruction::PUSH1), 0x00, bytes({byte(eth::Instruction::PUSH1), 0x00,
byte(eth::Instruction::SIGNEXTEND), byte(eth::Instruction::SIGNEXTEND),
byte(eth::Instruction::PUSH32)}) + bytes(31, 0xff) + bytes(1, 0x7f) + byte(eth::Instruction::ADD),
bytes({byte(eth::Instruction::ADD),
byte(eth::Instruction::PUSH1), 0x01, byte(eth::Instruction::PUSH1), 0x01,
byte(eth::Instruction::SIGNEXTEND)})); byte(eth::Instruction::SIGNEXTEND)}));
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end()); BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());

8
test/state.cpp

@ -54,13 +54,7 @@ void doStateTests(json_spirit::mValue& v, bool _fillin)
ImportTest importer(o, _fillin); ImportTest importer(o, _fillin);
if (_fillin) State theState = importer.m_statePre;
{
importer.code = importer.m_statePre.code(importer.m_environment.myAddress);
importer.m_environment.code = importer.code;
}
State theState = importer.m_statePre;
bytes tx = importer.m_transaction.rlp(); bytes tx = importer.m_transaction.rlp();
bytes output; bytes output;

35
test/tmpFiller.json

@ -1,35 +0,0 @@
{
"CallRecursiveBomb2": {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"currentNumber" : "0",
"currentGasLimit" : "10000000",
"currentDifficulty" : "256",
"currentTimestamp" : 1,
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
},
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "20000000",
"nonce" : 0,
"code" : "{ [[ 0 ]] (+ (SLOAD 0) 1) [[ 1 ]] (CALL (- (GAS) 224) (ADDRESS) 0 0 0 0 0) }",
"storage": {}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "1000000000000000000",
"nonce" : 0,
"code" : "",
"storage": {}
}
},
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "365224",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100000",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"data" : ""
}
}
}

2
test/vm.cpp

@ -290,7 +290,7 @@ void doVMTests(json_spirit::mValue& v, bool _fillin)
o["pre"] = mValue(fev.exportState()); o["pre"] = mValue(fev.exportState());
fev.importExec(o["exec"].get_obj()); fev.importExec(o["exec"].get_obj());
if (!fev.code.size()) if (fev.code.empty())
{ {
fev.thisTxCode = get<3>(fev.addresses.at(fev.myAddress)); fev.thisTxCode = get<3>(fev.addresses.at(fev.myAddress));
fev.code = fev.thisTxCode; fev.code = fev.thisTxCode;

Loading…
Cancel
Save