From b5aad086b0c029886f5e8c4a537904f8cc989b5d Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Thu, 15 Jun 2017 17:15:33 +0200 Subject: [PATCH] Rollback of NewCode recovers the original code This addresses #4130 together with the corresponding change in the test. --- libethereum/State.cpp | 7 +++++-- libethereum/State.h | 10 +++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/libethereum/State.cpp b/libethereum/State.cpp index e8d08b34d32..eb414614291 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -450,8 +450,8 @@ bytes const& State::code(Address const& _addr) const void State::setNewCode(Address const& _address, bytes&& _code) { + m_changeLog.emplace_back(_address, code(_address)); m_cache[_address].setNewCode(std::move(_code)); - m_changeLog.emplace_back(Change::NewCode, _address); } h256 State::codeHash(Address const& _a) const @@ -512,7 +512,10 @@ void State::rollback(size_t _savepoint) m_cache.erase(change.address); break; case Change::NewCode: - account.resetCode(); + if (change.oldCode.empty()) + account.resetCode(); + else + account.setNewCode(std::move(change.oldCode)); break; case Change::Touch: account.untouch(); diff --git a/libethereum/State.h b/libethereum/State.h index dbdd2990a88..2576b679171 100644 --- a/libethereum/State.h +++ b/libethereum/State.h @@ -128,16 +128,24 @@ struct Change Address address; ///< Changed account address. u256 value; ///< Change value, e.g. balance, storage. u256 key; ///< Storage key. Last because used only in one case. + bytes oldCode; ///< Code overwritten by CREATE, empty except in case of address collision. /// Helper constructor to make change log update more readable. Change(Kind _kind, Address const& _addr, u256 const& _value = 0): kind(_kind), address(_addr), value(_value) - {} + { + assert(_kind != NewCode); // For this the special constructor needs to be used. + } /// Helper constructor especially for storage change log. Change(Address const& _addr, u256 const& _key, u256 const& _value): kind(Storage), address(_addr), value(_value), key(_key) {} + + /// Helper constructor especially for new code change log. + Change(Address const& _addr, bytes const& _oldCode): + kind(NewCode), address(_addr), oldCode(_oldCode) + {} }; using ChangeLog = std::vector;