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/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/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))