diff --git a/alethzero/Transact.cpp b/alethzero/Transact.cpp
index 6f52548c7..1ff3427e3 100644
--- a/alethzero/Transact.cpp
+++ b/alethzero/Transact.cpp
@@ -338,7 +338,7 @@ void Transact::rejigData()
}
if (er.codeDeposit == CodeDeposit::Failed)
{
- bail("
ERROR Code deposit failed due to insufficient gas
");
+ bail("ERROR Code deposit failed due to insufficient gas; " + QString::fromStdString(toString(er.gasForDeposit)) + " GAS < " + QString::fromStdString(toString(er.depositSize)) + " bytes * " + QString::fromStdString(toString(c_createDataGas)) + "GAS/byte
");
return;
}
diff --git a/libethcore/Ethasher.cpp b/libethcore/Ethasher.cpp
index 79a2fdea3..880bc139a 100644
--- a/libethcore/Ethasher.cpp
+++ b/libethcore/Ethasher.cpp
@@ -112,17 +112,24 @@ bool Ethasher::verify(BlockInfo const& _header)
h256 boundary = u256((bigint(1) << 256) / _header.difficulty);
- bool ret = ethash_quick_check_difficulty(
+ bool quick = ethash_quick_check_difficulty(
_header.headerHash(WithoutNonce).data(),
(uint64_t)(u64)_header.nonce,
_header.mixHash.data(),
boundary.data());
-#if ETH_DEBUG
+#if !ETH_DEBUG
+ if (!quick)
+ return false;
+#endif
+
auto result = eval(_header);
- if ((result.value <= boundary && result.mixHash == _header.mixHash) != ret)
+ bool slow = result.value <= boundary && result.mixHash == _header.mixHash;
+
+#if ETH_DEBUG
+ if (!quick && slow)
{
- cwarn << "Assertion failure coming: evaluated result gives different outcome to ethash_quick_check_difficulty";
+ cwarn << "WARNING: evaluated result gives true whereas ethash_quick_check_difficulty gives false.";
cwarn << "headerHash:" << _header.headerHash(WithoutNonce);
cwarn << "nonce:" << _header.nonce;
cwarn << "mixHash:" << _header.mixHash;
@@ -131,12 +138,9 @@ bool Ethasher::verify(BlockInfo const& _header)
cwarn << "result.value:" << result.value;
cwarn << "result.mixHash:" << result.mixHash;
}
- assert((result.value <= boundary) == ret);
- if (result.value <= boundary)
- assert(result.mixHash == _header.mixHash);
#endif
- return ret;
+ return slow;
}
Ethasher::Result Ethasher::eval(BlockInfo const& _header, Nonce const& _nonce)
diff --git a/libethcore/Params.h b/libethcore/Params.h
index 7520e49f1..62cf6b2d8 100644
--- a/libethcore/Params.h
+++ b/libethcore/Params.h
@@ -29,15 +29,15 @@ namespace eth
{
//--- BEGIN: AUTOGENERATED FROM /feeStructure.json
-extern u256 const c_genesisDifficulty;
-extern u256 const c_maximumExtraDataSize;
-extern u256 const c_epochDuration;
extern u256 const c_genesisGasLimit;
extern u256 const c_minGasLimit;
extern u256 const c_gasLimitBoundDivisor;
+extern u256 const c_genesisDifficulty;
extern u256 const c_minimumDifficulty;
extern u256 const c_difficultyBoundDivisor;
extern u256 const c_durationLimit;
+extern u256 const c_maximumExtraDataSize;
+extern u256 const c_epochDuration;
extern u256 const c_stackLimit;
extern u256 const c_tierStepGas[8]; ///< Once per operation, for a selection of them.
diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp
index dfd526bef..0b75a07af 100644
--- a/libethereum/Executive.cpp
+++ b/libethereum/Executive.cpp
@@ -46,7 +46,7 @@ u256 Executive::gasUsed() const
ExecutionResult Executive::executionResult() const
{
- return ExecutionResult(gasUsed(), m_excepted, m_newAddress, m_out, m_codeDeposit, m_ext ? m_ext->sub.refunds : 0);
+ return ExecutionResult(gasUsed(), m_excepted, m_newAddress, m_out, m_codeDeposit, m_ext ? m_ext->sub.refunds : 0, m_depositSize, m_gasForDeposit);
}
void Executive::accrueSubState(SubState& _parentContext)
@@ -221,6 +221,8 @@ bool Executive::go(OnOpFunc const& _onOp)
if (m_isCreation)
{
+ m_gasForDeposit = m_endGas;
+ m_depositSize = m_out.size();
if (m_out.size() * c_createDataGas <= m_endGas)
{
m_codeDeposit = CodeDeposit::Success;
@@ -228,6 +230,7 @@ bool Executive::go(OnOpFunc const& _onOp)
}
else
{
+
m_codeDeposit = CodeDeposit::Failed;
m_out.reset();
}
diff --git a/libethereum/Executive.h b/libethereum/Executive.h
index 3445ad407..158e86330 100644
--- a/libethereum/Executive.h
+++ b/libethereum/Executive.h
@@ -128,6 +128,8 @@ private:
unsigned m_depth = 0; ///< The context's call-depth.
bool m_isCreation = false; ///< True if the transaction creates a contract, or if create() is called.
+ unsigned m_depositSize = 0; ///< Amount of code of the creation's attempted deposit.
+ u256 m_gasForDeposit; ///< Amount of gas remaining for the code deposit phase.
CodeDeposit m_codeDeposit = CodeDeposit::None; ///< True if an attempted deposit failed due to lack of gas.
TransactionException m_excepted = TransactionException::None; ///< Details if the VM's execution resulted in an exception.
u256 m_endGas; ///< The final amount of gas for the transaction.
diff --git a/libethereum/State.cpp b/libethereum/State.cpp
index 378c60fa3..c52c90921 100644
--- a/libethereum/State.cpp
+++ b/libethereum/State.cpp
@@ -111,22 +111,36 @@ State::State(OverlayDB const& _db, BlockChain const& _bc, h256 _h):
m_state(&m_db),
m_blockReward(c_blockReward)
{
- // TODO THINK: is this necessary?
- m_state.init();
-
auto b = _bc.block(_h);
- BlockInfo bi;
- BlockInfo bip;
- if (_h)
- bi.populate(b);
- if (bi && bi.number)
- bip.populate(_bc.block(bi.parentHash));
- if (!_h || !bip)
+ BlockInfo bi(b);
+
+ if (!bi)
+ {
+ // Might be worth throwing here.
+ cwarn << "Invalid block given for state population: " << _h;
return;
- m_ourAddress = bi.coinbaseAddress;
+ }
- sync(_bc, bi.parentHash, bip);
- enact(&b, _bc);
+ if (bi.number)
+ {
+ // Non-genesis:
+
+ // 1. Start at parent's end state (state root).
+ BlockInfo bip;
+ bip.populate(_bc.block(bi.parentHash));
+ sync(_bc, bi.parentHash, bip);
+
+ // 2. Enact the block's transactions onto this state.
+ m_ourAddress = bi.coinbaseAddress;
+ enact(&b, _bc);
+ }
+ else
+ {
+ // Genesis required:
+ // We know there are no transactions, so just populate directly.
+ m_state.init();
+ sync(_bc, _h, bi);
+ }
}
State::State(State const& _s):
diff --git a/libethereum/Transaction.cpp b/libethereum/Transaction.cpp
index 502f089fb..3228eca70 100644
--- a/libethereum/Transaction.cpp
+++ b/libethereum/Transaction.cpp
@@ -88,12 +88,12 @@ Transaction::Transaction(bytesConstRef _rlpData, CheckSignature _checkSig)
}
catch (Exception& _e)
{
- _e << errinfo_name("invalid transaction format") << BadFieldError(field,toHex(rlp[field].data().toBytes()));
+ _e << errinfo_name("invalid transaction format") << BadFieldError(field, toHex(rlp[field].data().toBytes()));
throw;
}
}
-Address Transaction::safeSender() const noexcept
+Address const& Transaction::safeSender() const noexcept
{
try
{
@@ -102,11 +102,11 @@ Address Transaction::safeSender() const noexcept
catch (...)
{
cwarn << "safeSender() did throw an exception: " << boost::current_exception_diagnostic_information();
- return Address();
+ return NullAddress;
}
}
-Address Transaction::sender() const
+Address const& Transaction::sender() const
{
if (!m_sender)
{
diff --git a/libethereum/Transaction.h b/libethereum/Transaction.h
index bed291868..ab2c12b50 100644
--- a/libethereum/Transaction.h
+++ b/libethereum/Transaction.h
@@ -75,17 +75,30 @@ TransactionException toTransactionException(VMException const& _e);
struct ExecutionResult
{
ExecutionResult() = default;
- ExecutionResult(u256 _gasUsed, TransactionException _excepted, Address _newAddress, bytesConstRef _output, CodeDeposit _codeDeposit, u256 _gasRefund): gasUsed(_gasUsed), excepted(_excepted), newAddress(_newAddress), output(_output.toBytes()), codeDeposit(_codeDeposit), gasRefunded(_gasRefund) {}
+ ExecutionResult(u256 const& _gasUsed, TransactionException _excepted, Address const& _newAddress, bytesConstRef _output, CodeDeposit _codeDeposit, u256 const& _gasRefund, unsigned _depositSize, u256 const& _gasForDeposit):
+ gasUsed(_gasUsed),
+ excepted(_excepted),
+ newAddress(_newAddress),
+ output(_output.toBytes()),
+ codeDeposit(_codeDeposit),
+ gasRefunded(_gasRefund),
+ depositSize(_depositSize),
+ gasForDeposit(_gasForDeposit)
+ {}
u256 gasUsed = 0;
TransactionException excepted = TransactionException::Unknown;
Address newAddress;
bytes output;
CodeDeposit codeDeposit = CodeDeposit::None;
u256 gasRefunded = 0;
+ unsigned depositSize = 0;
+ u256 gasForDeposit;
};
std::ostream& operator<<(std::ostream& _out, ExecutionResult const& _er);
+static const Address NullAddress;
+
/// Encodes a transaction, ready to be exported to or freshly imported from RLP.
class Transaction
{
@@ -94,16 +107,16 @@ public:
Transaction() {}
/// Constructs a signed message-call transaction.
- Transaction(u256 _value, u256 _gasPrice, u256 _gas, Address const& _dest, bytes const& _data, u256 _nonce, Secret const& _secret): m_type(MessageCall), m_nonce(_nonce), m_value(_value), m_receiveAddress(_dest), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) { sign(_secret); }
+ Transaction(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, Address const& _dest, bytes const& _data, u256 const& _nonce, Secret const& _secret): m_type(MessageCall), m_nonce(_nonce), m_value(_value), m_receiveAddress(_dest), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) { sign(_secret); }
/// Constructs a signed contract-creation transaction.
- Transaction(u256 _value, u256 _gasPrice, u256 _gas, bytes const& _data, u256 _nonce, Secret const& _secret): m_type(ContractCreation), m_nonce(_nonce), m_value(_value), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) { sign(_secret); }
+ Transaction(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, bytes const& _data, u256 const& _nonce, Secret const& _secret): m_type(ContractCreation), m_nonce(_nonce), m_value(_value), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) { sign(_secret); }
/// Constructs an unsigned message-call transaction.
- Transaction(u256 _value, u256 _gasPrice, u256 _gas, Address const& _dest, bytes const& _data): m_type(MessageCall), m_value(_value), m_receiveAddress(_dest), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) {}
+ Transaction(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, Address const& _dest, bytes const& _data): m_type(MessageCall), m_value(_value), m_receiveAddress(_dest), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) {}
/// Constructs an unsigned contract-creation transaction.
- Transaction(u256 _value, u256 _gasPrice, u256 _gas, bytes const& _data): m_type(ContractCreation), m_value(_value), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) {}
+ Transaction(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, bytes const& _data): m_type(ContractCreation), m_value(_value), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) {}
/// Constructs a transaction from the given RLP.
explicit Transaction(bytesConstRef _rlp, CheckSignature _checkSig);
@@ -118,9 +131,9 @@ public:
bool operator!=(Transaction const& _c) const { return !operator==(_c); }
/// @returns sender of the transaction from the signature (and hash).
- Address sender() const;
+ Address const& sender() const;
/// Like sender() but will never throw. @returns a null Address if the signature is invalid.
- Address safeSender() const noexcept;
+ Address const& safeSender() const noexcept;
/// @returns true if transaction is non-null.
explicit operator bool() const { return m_type != NullTransaction; }
diff --git a/libp2p/Host.h b/libp2p/Host.h
index c161f8437..753be3150 100644
--- a/libp2p/Host.h
+++ b/libp2p/Host.h
@@ -96,7 +96,7 @@ public:
static std::string pocHost();
/// Register a peer-capability; all new peer connections will have this capability.
- template std::shared_ptr registerCapability(T* _t) { _t->m_host = this; auto ret = std::shared_ptr(_t); m_capabilities[std::make_pair(T::staticName(), T::staticVersion())] = ret; return ret; }
+ template std::shared_ptr registerCapability(T* _t) { _t->m_host = this; std::shared_ptr ret(_t); m_capabilities[std::make_pair(T::staticName(), T::staticVersion())] = ret; return ret; }
bool haveCapability(CapDesc const& _name) const { return m_capabilities.count(_name) != 0; }
CapDescs caps() const { CapDescs ret; for (auto const& i: m_capabilities) ret.push_back(i.first); return ret; }
diff --git a/libsolidity/ArrayUtils.cpp b/libsolidity/ArrayUtils.cpp
index bbf7f985a..58031390f 100644
--- a/libsolidity/ArrayUtils.cpp
+++ b/libsolidity/ArrayUtils.cpp
@@ -440,6 +440,110 @@ void ArrayUtils::retrieveLength(ArrayType const& _arrayType) const
}
}
+void ArrayUtils::accessIndex(ArrayType const& _arrayType) const
+{
+ ArrayType::Location location = _arrayType.getLocation();
+ eth::Instruction load =
+ location == ArrayType::Location::Storage ? eth::Instruction::SLOAD :
+ location == ArrayType::Location::Memory ? eth::Instruction::MLOAD :
+ eth::Instruction::CALLDATALOAD;
+
+ // retrieve length
+ if (!_arrayType.isDynamicallySized())
+ m_context << _arrayType.getLength();
+ else if (location == ArrayType::Location::CallData)
+ // length is stored on the stack
+ m_context << eth::Instruction::SWAP1;
+ else
+ m_context << eth::Instruction::DUP2 << load;
+ // stack:
+ // check out-of-bounds access
+ m_context << eth::Instruction::DUP2 << eth::Instruction::LT;
+ eth::AssemblyItem legalAccess = m_context.appendConditionalJump();
+ // out-of-bounds access throws exception (just STOP for now)
+ m_context << eth::Instruction::STOP;
+
+ m_context << legalAccess;
+ // stack:
+ if (_arrayType.isByteArray())
+ switch (location)
+ {
+ case ArrayType::Location::Storage:
+ // byte array index storage lvalue on stack (goal):
+ // [ =
+ m_context << u256(32) << eth::Instruction::SWAP2;
+ CompilerUtils(m_context).computeHashStatic();
+ // stack: 32 index data_ref
+ m_context
+ << eth::Instruction::DUP3 << eth::Instruction::DUP3
+ << eth::Instruction::DIV << eth::Instruction::ADD
+ // stack: 32 index (data_ref + index / 32)
+ << eth::Instruction::SWAP2 << eth::Instruction::SWAP1
+ << eth::Instruction::MOD;
+ break;
+ case ArrayType::Location::CallData:
+ // no lvalue, just retrieve the value
+ m_context
+ << eth::Instruction::ADD << eth::Instruction::CALLDATALOAD
+ << ((u256(0xff) << (256 - 8))) << eth::Instruction::AND;
+ break;
+ case ArrayType::Location::Memory:
+ solAssert(false, "Memory lvalues not yet implemented.");
+ }
+ else
+ {
+ // stack:
+ m_context << eth::Instruction::SWAP1;
+ if (_arrayType.isDynamicallySized())
+ {
+ if (location == ArrayType::Location::Storage)
+ CompilerUtils(m_context).computeHashStatic();
+ else if (location == ArrayType::Location::Memory)
+ m_context << u256(32) << eth::Instruction::ADD;
+ }
+ // stack:
+ switch (location)
+ {
+ case ArrayType::Location::CallData:
+ m_context
+ << eth::Instruction::SWAP1 << _arrayType.getBaseType()->getCalldataEncodedSize()
+ << eth::Instruction::MUL << eth::Instruction::ADD;
+ if (_arrayType.getBaseType()->isValueType())
+ CompilerUtils(m_context).loadFromMemoryDynamic(*_arrayType.getBaseType(), true, true, false);
+ break;
+ case ArrayType::Location::Storage:
+ m_context << eth::Instruction::SWAP1;
+ if (_arrayType.getBaseType()->getStorageBytes() <= 16)
+ {
+ // stack:
+ // goal:
+ // ][ = <(index % itemsPerSlot) * byteSize>
+ unsigned byteSize = _arrayType.getBaseType()->getStorageBytes();
+ solAssert(byteSize != 0, "");
+ unsigned itemsPerSlot = 32 / byteSize;
+ m_context << u256(itemsPerSlot) << eth::Instruction::SWAP2;
+ // stack: itemsPerSlot index data_ref
+ m_context
+ << eth::Instruction::DUP3 << eth::Instruction::DUP3
+ << eth::Instruction::DIV << eth::Instruction::ADD
+ // stack: itemsPerSlot index (data_ref + index / itemsPerSlot)
+ << eth::Instruction::SWAP2 << eth::Instruction::SWAP1
+ << eth::Instruction::MOD
+ << u256(byteSize) << eth::Instruction::MUL;
+ }
+ else
+ {
+ if (_arrayType.getBaseType()->getStorageSize() != 1)
+ m_context << _arrayType.getBaseType()->getStorageSize() << eth::Instruction::MUL;
+ m_context << eth::Instruction::ADD << u256(0);
+ }
+ break;
+ case ArrayType::Location::Memory:
+ solAssert(false, "Memory lvalues not yet implemented.");
+ }
+ }
+}
+
void ArrayUtils::incrementByteOffset(unsigned _byteSize, unsigned _byteOffsetPosition, unsigned _storageOffsetPosition) const
{
solAssert(_byteSize < 32, "");
diff --git a/libsolidity/ArrayUtils.h b/libsolidity/ArrayUtils.h
index 22c0646a5..dab40e2d6 100644
--- a/libsolidity/ArrayUtils.h
+++ b/libsolidity/ArrayUtils.h
@@ -70,6 +70,12 @@ public:
/// Stack pre: reference (excludes byte offset for dynamic storage arrays)
/// Stack post: reference length
void retrieveLength(ArrayType const& _arrayType) const;
+ /// Retrieves the value at a specific index. If the location is storage, only retrieves the
+ /// position.
+ /// Stack pre: reference [length] index
+ /// Stack post for storage: slot byte_offset
+ /// Stack post for calldata: value
+ void accessIndex(ArrayType const& _arrayType) const;
private:
/// Adds the given number of bytes to a storage byte offset counter and also increments
diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp
index 90568767b..daea21623 100644
--- a/libsolidity/ExpressionCompiler.cpp
+++ b/libsolidity/ExpressionCompiler.cpp
@@ -755,113 +755,20 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess)
{
ArrayType const& arrayType = dynamic_cast(baseType);
solAssert(_indexAccess.getIndexExpression(), "Index expression expected.");
- ArrayType::Location location = arrayType.getLocation();
- eth::Instruction load =
- location == ArrayType::Location::Storage ? eth::Instruction::SLOAD :
- location == ArrayType::Location::Memory ? eth::Instruction::MLOAD :
- eth::Instruction::CALLDATALOAD;
// remove storage byte offset
- if (location == ArrayType::Location::Storage)
+ if (arrayType.getLocation() == ArrayType::Location::Storage)
m_context << eth::Instruction::POP;
- // stack layout: []
_indexAccess.getIndexExpression()->accept(*this);
- // retrieve length
- if (!arrayType.isDynamicallySized())
- m_context << arrayType.getLength();
- else if (location == ArrayType::Location::CallData)
- // length is stored on the stack
- m_context << eth::Instruction::SWAP1;
- else
- m_context << eth::Instruction::DUP2 << load;
- // stack:
- // check out-of-bounds access
- m_context << eth::Instruction::DUP2 << eth::Instruction::LT;
- eth::AssemblyItem legalAccess = m_context.appendConditionalJump();
- // out-of-bounds access throws exception (just STOP for now)
- m_context << eth::Instruction::STOP;
-
- m_context << legalAccess;
- // stack:
- if (arrayType.isByteArray())
- switch (location)
- {
- case ArrayType::Location::Storage:
- // byte array index storage lvalue on stack (goal):
- // ][ =
- m_context << u256(32) << eth::Instruction::SWAP2;
- CompilerUtils(m_context).computeHashStatic();
- // stack: 32 index data_ref
- m_context
- << eth::Instruction::DUP3 << eth::Instruction::DUP3
- << eth::Instruction::DIV << eth::Instruction::ADD
- // stack: 32 index (data_ref + index / 32)
- << eth::Instruction::SWAP2 << eth::Instruction::SWAP1
- << eth::Instruction::MOD;
- setLValue(_indexAccess);
- break;
- case ArrayType::Location::CallData:
- // no lvalue, just retrieve the value
- m_context
- << eth::Instruction::ADD << eth::Instruction::CALLDATALOAD
- << ((u256(0xff) << (256 - 8))) << eth::Instruction::AND;
- break;
- case ArrayType::Location::Memory:
- solAssert(false, "Memory lvalues not yet implemented.");
- }
- else
+ // stack layout: []
+ ArrayUtils(m_context).accessIndex(arrayType);
+ if (arrayType.getLocation() == ArrayType::Location::Storage)
{
- // stack:
- m_context << eth::Instruction::SWAP1;
- if (arrayType.isDynamicallySized())
- {
- if (location == ArrayType::Location::Storage)
- CompilerUtils(m_context).computeHashStatic();
- else if (location == ArrayType::Location::Memory)
- m_context << u256(32) << eth::Instruction::ADD;
- }
- // stack:
- switch (location)
- {
- case ArrayType::Location::CallData:
- m_context
- << eth::Instruction::SWAP1 << arrayType.getBaseType()->getCalldataEncodedSize()
- << eth::Instruction::MUL << eth::Instruction::ADD;
- if (arrayType.getBaseType()->isValueType())
- CompilerUtils(m_context).loadFromMemoryDynamic(*arrayType.getBaseType(), true, true, false);
- break;
- case ArrayType::Location::Storage:
- m_context << eth::Instruction::SWAP1;
- if (arrayType.getBaseType()->getStorageBytes() <= 16)
- {
- // stack:
- // goal:
- // ][ = <(index % itemsPerSlot) * byteSize>
- unsigned byteSize = arrayType.getBaseType()->getStorageBytes();
- solAssert(byteSize != 0, "");
- unsigned itemsPerSlot = 32 / byteSize;
- m_context << u256(itemsPerSlot) << eth::Instruction::SWAP2;
- // stack: itemsPerSlot index data_ref
- m_context
- << eth::Instruction::DUP3 << eth::Instruction::DUP3
- << eth::Instruction::DIV << eth::Instruction::ADD
- // stack: itemsPerSlot index (data_ref + index / itemsPerSlot)
- << eth::Instruction::SWAP2 << eth::Instruction::SWAP1
- << eth::Instruction::MOD
- << u256(byteSize) << eth::Instruction::MUL;
- }
- else
- {
- if (arrayType.getBaseType()->getStorageSize() != 1)
- m_context << arrayType.getBaseType()->getStorageSize() << eth::Instruction::MUL;
- m_context << eth::Instruction::ADD << u256(0);
- }
+ if (arrayType.isByteArray())
+ setLValue(_indexAccess);
+ else
setLValueToStorageItem(_indexAccess);
- break;
- case ArrayType::Location::Memory:
- solAssert(false, "Memory lvalues not yet implemented.");
- }
}
}
else
diff --git a/libtestutils/BlockChainLoader.cpp b/libtestutils/BlockChainLoader.cpp
index eafab190e..898812b2a 100644
--- a/libtestutils/BlockChainLoader.cpp
+++ b/libtestutils/BlockChainLoader.cpp
@@ -28,57 +28,6 @@ using namespace dev;
using namespace dev::test;
using namespace dev::eth;
-namespace dev
-{
-namespace test
-{
-dev::eth::BlockInfo toBlockInfo(Json::Value const& _json);
-bytes toGenesisBlock(Json::Value const& _json);
-}
-}
-
-dev::eth::BlockInfo dev::test::toBlockInfo(Json::Value const& _json)
-{
- RLPStream rlpStream;
- auto size = _json.getMemberNames().size();
- rlpStream.appendList(_json["hash"].empty() ? size : (size - 1));
- rlpStream << fromHex(_json["parentHash"].asString());
- rlpStream << fromHex(_json["uncleHash"].asString());
- rlpStream << fromHex(_json["coinbase"].asString());
- rlpStream << fromHex(_json["stateRoot"].asString());
- rlpStream << fromHex(_json["transactionsTrie"].asString());
- rlpStream << fromHex(_json["receiptTrie"].asString());
- rlpStream << fromHex(_json["bloom"].asString());
- rlpStream << bigint(_json["difficulty"].asString());
- rlpStream << bigint(_json["number"].asString());
- rlpStream << bigint(_json["gasLimit"].asString());
- rlpStream << bigint(_json["gasUsed"].asString());
- rlpStream << bigint(_json["timestamp"].asString());
- rlpStream << fromHex(_json["extraData"].asString());
- rlpStream << fromHex(_json["mixHash"].asString());
- rlpStream << fromHex(_json["nonce"].asString());
-
- BlockInfo result;
- RLP rlp(rlpStream.out());
- result.populateFromHeader(rlp, IgnoreNonce);
- return result;
-}
-
-bytes dev::test::toGenesisBlock(Json::Value const& _json)
-{
- BlockInfo bi = toBlockInfo(_json);
- RLPStream rlpStream;
- bi.streamRLP(rlpStream, WithNonce);
-
- RLPStream fullStream(3);
- fullStream.appendRaw(rlpStream.out());
- fullStream.appendRaw(RLPEmptyList);
- fullStream.appendRaw(RLPEmptyList);
- bi.verifyInternals(&fullStream.out());
-
- return fullStream.out();
-}
-
BlockChainLoader::BlockChainLoader(Json::Value const& _json)
{
// load pre state
@@ -86,7 +35,7 @@ BlockChainLoader::BlockChainLoader(Json::Value const& _json)
m_state = sl.state();
// load genesisBlock
- m_bc.reset(new BlockChain(toGenesisBlock(_json["genesisBlockHeader"]), m_dir.path(), true));
+ m_bc.reset(new BlockChain(fromHex(_json["genesisRLP"].asString()), m_dir.path(), true));
// load blocks
for (auto const& block: _json["blocks"])
diff --git a/libwhisper/Message.cpp b/libwhisper/Message.cpp
index 07bcea0c1..4375e0727 100644
--- a/libwhisper/Message.cpp
+++ b/libwhisper/Message.cpp
@@ -58,10 +58,10 @@ Message::Message(Envelope const& _e, FullTopic const& _fk, Secret const& _s)
// get key from decrypted topic key: just xor
h256 tk = h256(bytesConstRef(&(_e.data())).cropped(32 * topicIndex, 32));
bytesConstRef cipherText = bytesConstRef(&(_e.data())).cropped(32 * _e.topic().size());
- cnote << "Decrypting(" << topicIndex << "): " << topicSecret << tk << (topicSecret ^ tk) << toHex(cipherText);
+// cdebug << "Decrypting(" << topicIndex << "): " << topicSecret << tk << (topicSecret ^ tk) << toHex(cipherText);
if (!decryptSym(topicSecret ^ tk, cipherText, b))
return;
- cnote << "Got: " << toHex(b);
+// cdebug << "Got: " << toHex(b);
}
if (populate(b))
]