/* This file is part of cpp-ethereum. cpp-ethereum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. cpp-ethereum is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ #pragma once #include #include namespace dev { namespace eth { struct EVMSchedule { EVMSchedule(): tierStepGas(std::array{{0, 2, 3, 5, 8, 10, 20, 0}}) {} EVMSchedule(bool _efcd, bool _hdc, unsigned const& _txCreateGas): exceptionalFailedCodeDeposit(_efcd), haveDelegateCall(_hdc), tierStepGas(std::array{{0, 2, 3, 5, 8, 10, 20, 0}}), txCreateGas(_txCreateGas) {} unsigned accountVersion = 0; bool exceptionalFailedCodeDeposit = true; bool haveDelegateCall = true; bool eip150Mode = false; bool eip158Mode = false; bool eip1283Mode = false; bool haveBitwiseShifting = false; bool haveRevert = false; bool haveReturnData = false; bool haveStaticCall = false; bool haveCreate2 = false; bool haveExtcodehash = false; bool haveChainID = false; bool haveSelfbalance = false; std::array tierStepGas; unsigned expGas = 10; unsigned expByteGas = 10; unsigned sha3Gas = 30; unsigned sha3WordGas = 6; unsigned sloadGas = 50; unsigned sstoreSetGas = 20000; unsigned sstoreResetGas = 5000; unsigned sstoreUnchangedGas = 200; unsigned sstoreRefundGas = 15000; unsigned sstoreRefundNonzeroGas = 4800; unsigned jumpdestGas = 1; unsigned logGas = 375; unsigned logDataGas = 8; unsigned logTopicGas = 375; unsigned createGas = 32000; unsigned callGas = 40; unsigned callStipend = 2300; unsigned callValueTransferGas = 9000; unsigned callNewAccountGas = 25000; unsigned suicideRefundGas = 24000; unsigned memoryGas = 3; unsigned quadCoeffDiv = 512; unsigned createDataGas = 200; unsigned txGas = 21000; unsigned txCreateGas = 53000; unsigned txDataZeroGas = 4; unsigned txDataNonZeroGas = 68; unsigned copyGas = 3; unsigned extcodesizeGas = 20; unsigned extcodecopyGas = 20; unsigned extcodehashGas = 400; unsigned balanceGas = 20; unsigned suicideGas = 0; unsigned blockhashGas = 20; unsigned maxCodeSize = unsigned(-1); boost::optional blockRewardOverwrite; bool staticCallDepthLimit() const { return !eip150Mode; } bool suicideChargesNewAccountGas() const { return eip150Mode; } bool emptinessIsNonexistence() const { return eip158Mode; } bool zeroValueTransferChargesNewAccountGas() const { return !eip158Mode; } }; static const EVMSchedule DefaultSchedule = EVMSchedule(); static const EVMSchedule FrontierSchedule = EVMSchedule(false, false, 21000); static const EVMSchedule HomesteadSchedule = EVMSchedule(true, true, 53000); static const EVMSchedule EIP150Schedule = [] { EVMSchedule schedule = HomesteadSchedule; schedule.eip150Mode = true; schedule.extcodesizeGas = 700; schedule.extcodecopyGas = 700; schedule.balanceGas = 400; schedule.sloadGas = 200; schedule.callGas = 700; schedule.suicideGas = 5000; return schedule; }(); static const EVMSchedule EIP158Schedule = [] { EVMSchedule schedule = EIP150Schedule; schedule.expByteGas = 50; schedule.eip158Mode = true; schedule.maxCodeSize = 0x6000; return schedule; }(); static const EVMSchedule ByzantiumSchedule = [] { EVMSchedule schedule = EIP158Schedule; schedule.haveRevert = true; schedule.haveReturnData = true; schedule.haveStaticCall = true; schedule.blockRewardOverwrite = {3 * ether}; return schedule; }(); static const EVMSchedule EWASMSchedule = [] { EVMSchedule schedule = ByzantiumSchedule; schedule.maxCodeSize = std::numeric_limits::max(); return schedule; }(); static const EVMSchedule ConstantinopleSchedule = [] { EVMSchedule schedule = ByzantiumSchedule; schedule.haveCreate2 = true; schedule.haveBitwiseShifting = true; schedule.haveExtcodehash = true; schedule.eip1283Mode = true; schedule.blockRewardOverwrite = {2 * ether}; return schedule; }(); static const EVMSchedule ConstantinopleFixSchedule = [] { EVMSchedule schedule = ConstantinopleSchedule; schedule.eip1283Mode = false; return schedule; }(); static const EVMSchedule IstanbulSchedule = [] { EVMSchedule schedule = ConstantinopleFixSchedule; schedule.txDataNonZeroGas = 16; schedule.sloadGas = 800; schedule.balanceGas = 700; schedule.extcodehashGas = 700; schedule.haveChainID = true; schedule.haveSelfbalance = true; return schedule; }(); static const EVMSchedule ExperimentalSchedule = [] { EVMSchedule schedule = IstanbulSchedule; schedule.accountVersion = 1; schedule.blockhashGas = 800; return schedule; }(); inline EVMSchedule const& latestScheduleForAccountVersion(u256 const& _version) { if (_version == 0) return IstanbulSchedule; else if (_version == ExperimentalSchedule.accountVersion) return ExperimentalSchedule; else { // This should not happen, as all existing accounts // are created either with version 0 or with one of fork's versions assert(false); return DefaultSchedule; } } } }