-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Selfdestruct optimizations for Frontier and Homestead #5718
Conversation
26866ed
to
6b639ee
Compare
6b639ee
to
fcb1f3d
Compare
Codecov Report
@@ Coverage Diff @@
## master #5718 +/- ##
==========================================
+ Coverage 63.2% 63.21% +<.01%
==========================================
Files 353 353
Lines 30271 30272 +1
Branches 3390 3391 +1
==========================================
+ Hits 19134 19135 +1
+ Misses 9904 9900 -4
- Partials 1233 1237 +4 |
libaleth-interpreter/VM.cpp
Outdated
m_runGas += VMSchedule::callNewAccount; | ||
// After EIP158 zero-value suicides do not have to pay account creation gas. | ||
u256 const balance = | ||
fromEvmC(m_context->host->get_balance(m_context, &m_message->destination)); |
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.
This is still "wrong", because get_balance()
will be executed in case of m_rev == EVMC_TANGERINE_WHISTLE
where its value does not matter.
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.
@chfast Ah thought that the changes should apply to Homestead / Frontier, I'll take another look at which hard forks the EIPs were enabled on. According to this they were both enabled on Tangerine Whistle but that's not right if we don't care about the balance on Tangerine Whistle: https://ethereum.stackexchange.com/questions/13014/please-provide-a-summary-of-the-ethereum-hard-forks
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.
No need to check external sources. The logic here is correct. Just if you check the if
at https://github.com/ethereum/aleth/pull/5718/files#diff-4a2862de6e660dc5045835d8879be719R389 you will see that:
- you can swap the checks in
||
. - The balance has be checked only if the first condition is false.
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.
@chfast I'm confused...the line that you're referring to comes after balance retrieval so changing the checks will have no impact on whether or not we check the balance on Tangerine Whistle?
Line in question:
aleth/libaleth-interpreter/VM.cpp
Line 389 in fcb1f3d
if (balance > 0 || m_rev == EVMC_TANGERINE_WHISTLE) |
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.
@chfast I'm still a little confused about this part of the aleth-interpreter changes:
aleth/libaleth-interpreter/VM.cpp
Lines 383 to 388 in 29ed24e
// Self-destructs only have gas cost starting with Tangerine Whistle | |
if (m_rev >= EVMC_TANGERINE_WHISTLE) | |
{ | |
// After EIP158 zero-value suicides do not have to pay account creation gas. | |
if (m_rev == EVMC_TANGERINE_WHISTLE || | |
fromEvmC(m_context->host->get_balance(m_context, &m_message->destination)) > 0) |
The check for EVMC_TANGERINE_WHISTLE on line 387 implies that on that hard fork, all suicides (0-value or otherwise) have an account-creation charge. This implies that EIP158 (which removes the account-creation charge for 0-value selfdestructs) was included in Spurious Dragon, but the following says that it was included in Tangerine Whistle: https://ethereum.stackexchange.com/questions/13014/please-provide-a-summary-of-the-ethereum-hard-forks
So to summarize, EIP158 was included in Spurious Dragon and not Tangerine Whistle?
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.
EIP-158 was activated at block 2'675'000 which is Spurious Dragon
"EIP158ForkBlock": "0x28d138", |
in EIPs actually EIP-161 supercedes EIP-158 and is listed in meta-EIP https://eips.ethereum.org/EIPS/eip-607
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.
@gumb0 Thanks for the info! Is there a reliable list that you can recommend of hard forks + the block numbers that they occurred at?
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.
I think meta-EIPs should correctly reflect the reality of mainnet https://eips.ethereum.org/meta
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.
@gumb0 Perfect, that's exactly what I was looking for!
libevm/LegacyVM.cpp
Outdated
// Starting with EIP150, self-destructs need to pay both gas cost and account creation | ||
// gas cost. Starting with EIP158, 0-value self-destructs don't need to pay this account | ||
// creation cost. | ||
if (m_schedule->zeroValueTransferChargesNewAccountGas() || |
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.
aleth-interpreter part is quite clear, but I'm not the fan of the change in LegacyVM.
I think we can assume that eip158 is always activated not earlier than eip150, and then simplify it to very similar to interpterter's version:
if (m_schedule->suicideChargesNewAccountGas())
{
if (m_schedule->zeroValueTransferChargesNewAccountGas() || m_ext->balance(m_ext->myAddress) > 0)
{
if (!m_ext->exists(dest))
m_runGas += m_schedule->callNewAccountGas;
}
}
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.
Maybe add assert(m_schedule->zeroValueTransferChargesNewAccountGas() || m_schedule->suicideChargesNewAccountGas())
- this was your first condition, and it should be always true when eip158 comes after eip150
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.
@gumb0 / @chfast : After taking another look at this I don't like the feature-style checks in this opcode...I think they end up making things more confusing since they add a layer of indirection between our test case and the EIPs being checked. I think that a simpler / more intuitive approach would be something like this:
// Starting with EIP150, self-destructs need to pay both gas cost and account creation
// gas cost. Starting with EIP158, 0-value self-destructs don't need to pay this account
// creation cost.
if (m_schedule->eip150Mode || (m_schedule->eip158Mode && m_ext->balance(m_ext->myAddress) > 0))
{
if (!m_ext->exists(dest))
m_runGas += m_schedule->callNewAccountGas;
}
This assumes that m_schedule->eip150Mode
will not be true for the Spurious Dragon schedule.
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.
Agree that using eips would be simpler, but
This assumes that m_schedule->eip150Mode will not be true for the Spurious Dragon schedule.
this assumption is wrong, because eip150Mode
is true for Tangerine Whistle and further, so including Spurious Dragon.
So I think it should be
if (m_schedule->eip150Mode && (!m_schedule->eip158Mode || m_ext->balance(m_ext->myAddress) > 0))
{
if (!m_ext->exists(dest))
m_runGas += m_schedule->callNewAccountGas;
}
or leave it as 3 nested ifs as I suggested above similar to interpreter version.
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.
Still ok for me.
libaleth-interpreter/VM.cpp
Outdated
@@ -377,21 +377,19 @@ void VM::interpretCases() | |||
if (m_message->flags & EVMC_STATIC) | |||
throwDisallowedStateChange(); | |||
|
|||
// Self-destructs only have gas cost starting with Tangerine Whistle | |||
m_runGas = m_rev >= EVMC_TANGERINE_WHISTLE ? 5000 : 0; |
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.
This line is gone. Please rebase.
23b9e43
to
1aad58d
Compare
Rebased |
c47376b
to
e701f4e
Compare
e701f4e
to
e18ecad
Compare
Update balance/account checks for SUICIDE opcode in aleth-interpreter and LegacyVM so that they are only performed when necessary.
e18ecad
to
b565b8c
Compare
Squashed all of the code commits together since I don't think 5 commits is necessary for such a small set of changes. |
Fix #5682
Since self-destruct operations have no gas cost on Frontier and Homestead, avoid checking the contract balance and destination account existence when executing a self-destruct in both aleth-interpreter and LegacyVM.