-
Notifications
You must be signed in to change notification settings - Fork 2.2k
EIP98 - Remove state root hash from transaction receipt #4035
Changes from all commits
f0da2f3
0dd3e54
7bc23b5
1ce0eb6
d01152a
23a9cf5
ce0e0a2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,11 +31,11 @@ | |
#include <libethcore/Exceptions.h> | ||
#include <libevm/VMFactory.h> | ||
#include "BlockChain.h" | ||
#include "Block.h" | ||
#include "CodeSizeCache.h" | ||
#include "Defaults.h" | ||
#include "ExtVM.h" | ||
#include "Executive.h" | ||
#include "BlockChain.h" | ||
#include "TransactionQueue.h" | ||
|
||
using namespace std; | ||
|
@@ -49,6 +49,20 @@ const char* StateDetail::name() { return EthViolet "⚙" EthWhite " ◌"; } | |
const char* StateTrace::name() { return EthViolet "⚙" EthGray " ◎"; } | ||
const char* StateChat::name() { return EthViolet "⚙" EthWhite " ◌"; } | ||
|
||
namespace | ||
{ | ||
|
||
void executeTransaction(Executive& _e, Transaction const& _t, OnOpFunc const& _onOp) | ||
{ | ||
_e.initialize(_t); | ||
|
||
if (!_e.execute()) | ||
_e.go(_onOp); | ||
_e.finalize(); | ||
} | ||
|
||
} | ||
|
||
State::State(u256 const& _accountStartNonce, OverlayDB const& _db, BaseState _bs): | ||
m_db(_db), | ||
m_state(&m_db), | ||
|
@@ -523,13 +537,9 @@ std::pair<ExecutionResult, TransactionReceipt> State::execute(EnvInfo const& _en | |
Executive e(*this, _envInfo, _sealEngine); | ||
ExecutionResult res; | ||
e.setResultRecipient(res); | ||
e.initialize(_t); | ||
|
||
// OK - transaction looks valid - execute. | ||
u256 startGasUsed = _envInfo.gasUsed(); | ||
if (!e.execute()) | ||
e.go(onOp); | ||
e.finalize(); | ||
u256 const startGasUsed = _envInfo.gasUsed(); | ||
executeTransaction(e, _t, onOp); | ||
|
||
if (_p == Permanence::Reverted) | ||
m_cache.clear(); | ||
|
@@ -539,7 +549,24 @@ std::pair<ExecutionResult, TransactionReceipt> State::execute(EnvInfo const& _en | |
commit(removeEmptyAccounts ? State::CommitBehaviour::RemoveEmptyAccounts : State::CommitBehaviour::KeepEmptyAccounts); | ||
} | ||
|
||
return make_pair(res, TransactionReceipt(rootHash(), startGasUsed + e.gasUsed(), e.logs())); | ||
TransactionReceipt const receipt = _envInfo.number() >= _sealEngine.chainParams().u256Param("metropolisForkBlock") ? | ||
TransactionReceipt(startGasUsed + e.gasUsed(), e.logs()) : | ||
TransactionReceipt(rootHash(), startGasUsed + e.gasUsed(), e.logs()); | ||
return make_pair(res, receipt); | ||
} | ||
|
||
void State::executeBlockTransactions(Block const& _block, unsigned _txCount, LastHashes const& _lastHashes, SealEngineFace const& _sealEngine) | ||
{ | ||
u256 gasUsed = 0; | ||
for (unsigned i = 0; i < _txCount; ++i) | ||
{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The whole for-loop body should be a helper function also used elsewhere - or are the cases there more complicated? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, the other case - There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wanted to move it to a separate function for a long time. |
||
EnvInfo envInfo(_block.info(), _lastHashes, gasUsed); | ||
|
||
Executive e(*this, envInfo, _sealEngine); | ||
executeTransaction(e, _block.pending()[i], OnOpFunc()); | ||
|
||
gasUsed += e.gasUsed(); | ||
} | ||
} | ||
|
||
std::ostream& dev::eth::operator<<(std::ostream& _out, State const& _s) | ||
|
@@ -617,3 +644,17 @@ std::ostream& dev::eth::operator<<(std::ostream& _out, State const& _s) | |
} | ||
return _out; | ||
} | ||
|
||
State& dev::eth::createIntermediateState(State& o_s, Block const& _block, unsigned _txIndex, BlockChain const& _bc) | ||
{ | ||
o_s = _block.state(); | ||
u256 const rootHash = _block.stateRootBeforeTx(_txIndex); | ||
if (rootHash) | ||
o_s.setRoot(rootHash); | ||
else | ||
{ | ||
o_s.setRoot(_block.stateRootBeforeTx(0)); | ||
o_s.executeBlockTransactions(_block, _txIndex, _bc.lastHashes(_block.info().parentHash()), *_bc.sealEngine()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need a check for dereferencing sealEngine here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think so. I've spot it before, it should not be a pointer type. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, it's always non-null in practice |
||
} | ||
return o_s; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,11 +28,21 @@ using namespace dev::eth; | |
TransactionReceipt::TransactionReceipt(bytesConstRef _rlp) | ||
{ | ||
RLP r(_rlp); | ||
m_stateRoot = (h256)r[0]; | ||
m_gasUsed = (u256)r[1]; | ||
m_bloom = (LogBloom)r[2]; | ||
for (auto const& i: r[3]) | ||
if (!r.isList() || r.itemCount() < 3 || r.itemCount() > 4) | ||
DEV_SIMPLE_EXCEPTION(InvalidTransactionReceiptFormat); | ||
|
||
size_t gasUsedIndex = 0; | ||
if (r.itemCount() == 4) | ||
{ | ||
m_stateRoot = (h256)r[0]; | ||
gasUsedIndex = 1; | ||
} | ||
|
||
m_gasUsed = (u256)r[gasUsedIndex]; | ||
m_bloom = (LogBloom)r[gasUsedIndex + 1]; | ||
for (auto const& i : r[gasUsedIndex + 2]) | ||
m_log.emplace_back(i); | ||
|
||
} | ||
|
||
TransactionReceipt::TransactionReceipt(h256 _root, u256 _gasUsed, LogEntries const& _log): | ||
|
@@ -44,7 +54,13 @@ TransactionReceipt::TransactionReceipt(h256 _root, u256 _gasUsed, LogEntries con | |
|
||
void TransactionReceipt::streamRLP(RLPStream& _s) const | ||
{ | ||
_s.appendList(4) << m_stateRoot << m_gasUsed << m_bloom; | ||
if (m_stateRoot) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you document this is the header? Perhaps best to put that into the class description. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added a comment |
||
_s.appendList(4) << m_stateRoot; | ||
else | ||
_s.appendList(3); | ||
|
||
_s << m_gasUsed << m_bloom; | ||
|
||
_s.appendList(m_log.size()); | ||
for (LogEntry const& l: m_log) | ||
l.streamRLP(_s); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These were not used