From 798f636c239ffe40f01144204ac8927098754fc3 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 2 Mar 2015 15:30:22 +0100 Subject: [PATCH] New gas pricing for PoC-9. --- libethereum/ExtVM.h | 2 +- libevm/FeeStructure.cpp | 84 ++++++++++++++++++-------------------- libevm/FeeStructure.h | 14 +++---- libevm/VM.cpp | 14 ++++--- libevmcore/Instruction.cpp | 2 +- 5 files changed, 55 insertions(+), 61 deletions(-) diff --git a/libethereum/ExtVM.h b/libethereum/ExtVM.h index 2ff270de5..40ff62175 100644 --- a/libethereum/ExtVM.h +++ b/libethereum/ExtVM.h @@ -70,7 +70,7 @@ public: virtual u256 txCount(Address _a) override final { return m_s.transactionsFrom(_a); } /// Does the account exist? - virtual bool exists(Address _a) override final { return m_s.addressInUse(_a); } + virtual bool exists(Address _a) { return m_s.addressInUse(_a); } /// Suicide the associated contract to the given address. virtual void suicide(Address _a) override final diff --git a/libevm/FeeStructure.cpp b/libevm/FeeStructure.cpp index 78c6ebfb2..1c1bf8a9e 100644 --- a/libevm/FeeStructure.cpp +++ b/libevm/FeeStructure.cpp @@ -22,48 +22,44 @@ #include "FeeStructure.h" using namespace std; -namespace dev -{ -namespace eth -{ - -//--- BEGIN: AUTOGENERATED FROM /feeStructure.json -u256 const c_tierStepGas[] = {0, 2, 3, 5, 8, 10, 20, 0}; -u256 const c_expGas = 10; -u256 const c_expByteGas = 10; -u256 const c_sha3Gas = 30; -u256 const c_sha3WordGas = 6; -u256 const c_sloadGas = 50; -u256 const c_sstoreSetGas = 20000; -u256 const c_sstoreResetGas = 5000; -u256 const c_sstoreClearGas = 5000; -u256 const c_sstoreRefundGas = 15000; -u256 const c_jumpdestGas = 1; -u256 const c_logGas = 375; -u256 const c_logDataGas = 8; -u256 const c_logTopicGas = 375; -u256 const c_createGas = 32000; -u256 const c_callGas = 40; -u256 const c_callStipend = 2300; -u256 const c_callValueTransferGas = 9000; -u256 const c_callNewAccountGas = 25000; -u256 const c_suicideRefundGas = 24000; -u256 const c_memoryGas = 3; -u256 const c_quadCoeffDiv = 512; -u256 const c_createDataGas = 200; -u256 const c_txGas = 21000; -u256 const c_txDataZeroGas = 4; -u256 const c_txDataNonZeroGas = 68; -u256 const c_copyGas = 3; -u256 const c_ecrecoverGas = 3000; -u256 const c_sha256Gas = 60; -u256 const c_sha256WordGas = 12; -u256 const c_ripemd160Gas = 600; -u256 const c_ripemd160WordGas = 120; -u256 const c_identityGas = 15; -u256 const c_identityWordGas = 3; -//--- END: AUTOGENERATED FROM /feeStructure.json - -} -} +using namespace dev; +using namespace dev::eth; + +u256 const dev::eth::c_tierStepGas[8] = { 0, 2, 3, 5, 8, 10, 20, 0 }; +u256 const dev::eth::c_expGas = 10; +u256 const dev::eth::c_expByteGas = 10; + +u256 const dev::eth::c_sha3Gas = 30; +u256 const dev::eth::c_sha3WordGas = 6; + +u256 const dev::eth::c_sloadGas = 50; +u256 const dev::eth::c_sstoreSetGas = 20000; +u256 const dev::eth::c_sstoreResetGas = 5000; +u256 const dev::eth::c_sstoreClearGas = 5000; +u256 const dev::eth::c_sstoreRefundGas = 15000; +u256 const dev::eth::c_jumpdestGas = 1; + +u256 const dev::eth::c_logGas = 2000; +u256 const dev::eth::c_logDataGas = 8; +u256 const dev::eth::c_logTopicGas = 2000; + +u256 const dev::eth::c_createGas = 32000; + +u256 const dev::eth::c_callGas = 40; +u256 const dev::eth::c_callValueTransferGas = 6700; +u256 const dev::eth::c_callNewAccountGas = 25000; + +u256 const dev::eth::c_suicideRefundGas = 24000; + +u256 const dev::eth::c_memoryGas = 3; +u256 const dev::eth::c_quadCoeffDiv = 512; + + +u256 const dev::eth::c_createDataGas = 200; +u256 const dev::eth::c_txGas = 21000; +u256 const dev::eth::c_txDataZeroGas = 37; +u256 const dev::eth::c_txDataNonZeroGas = 2; + +u256 const dev::eth::c_copyGas = 3; + diff --git a/libevm/FeeStructure.h b/libevm/FeeStructure.h index 9109347dc..1b58c80e9 100644 --- a/libevm/FeeStructure.h +++ b/libevm/FeeStructure.h @@ -28,41 +28,37 @@ namespace dev namespace eth { -//--- BEGIN: AUTOGENERATED FROM /feeStructure.json extern u256 const c_tierStepGas[8]; ///< Once per operation, for a selection of them. extern u256 const c_expGas; ///< Once per EXP instuction. extern u256 const c_expByteGas; ///< Times ceil(log256(exponent)) for the EXP instruction. + extern u256 const c_sha3Gas; ///< Once per SHA3 operation. extern u256 const c_sha3WordGas; ///< Once per word of the SHA3 operation's data. + extern u256 const c_copyGas; ///< Multiplied by the number of 32-byte words that are copied (round up) for any *COPY operation and added. + extern u256 const c_sloadGas; ///< Once per SLOAD operation. extern u256 const c_sstoreSetGas; ///< Once per SSTORE operation if the zeroness changes from zero. extern u256 const c_sstoreResetGas; ///< Once per SSTORE operation if the zeroness doesn't change. extern u256 const c_sstoreClearGas; ///< Once per SSTORE operation if the zeroness changes to zero. extern u256 const c_sstoreRefundGas; ///< Refunded gas, once per SSTORE operation if the zeroness changes to zero. extern u256 const c_jumpdestGas; ///< Once per JUMPDEST operation. + extern u256 const c_logGas; ///< Per LOG* operation. extern u256 const c_logDataGas; ///< Per byte in a LOG* operation's data. extern u256 const c_logTopicGas; ///< Multiplied by the * of the LOG*, per LOG transaction. e.g. LOG0 incurs 0 * c_txLogTopicGas, LOG4 incurs 4 * c_txLogTopicGas. extern u256 const c_createGas; ///< Once per CREATE operation & contract-creation transaction. extern u256 const c_createDataGas; extern u256 const c_callGas; ///< Once per CALL operation & message call transaction. -extern u256 const c_callStipend; ///< Free gas given at beginning of call. extern u256 const c_callNewAccountGas; ///< Paid for CALL when the destination address didn't exist prior. extern u256 const c_callValueTransferGas; ///< Paid for CALL when the value transfor is non-zero. extern u256 const c_suicideRefundGas; ///< Refunded following a suicide operation. + extern u256 const c_memoryGas; ///< Times the address of the (highest referenced byte in memory + 1). NOTE: referencing happens on read, write and in instructions such as RETURN and CALL. extern u256 const c_quadCoeffDiv; ///< Divisor for the quadratic particle of the memory cost equation. extern u256 const c_txGas; ///< Per transaction. NOTE: Not payable on data of calls between transactions. extern u256 const c_txDataZeroGas; ///< Per byte of data attached to a transaction that equals zero. NOTE: Not payable on data of calls between transactions. extern u256 const c_txDataNonZeroGas; ///< Per byte of data attached to a transaction that is not equal to zero. NOTE: Not payable on data of calls between transactions. -extern u256 const c_ecrecoverGas; -extern u256 const c_sha256Gas; -extern u256 const c_sha256WordGas; -extern u256 const c_ripemd160Gas; -extern u256 const c_ripemd160WordGas; -extern u256 const c_identityGas; -extern u256 const c_identityWordGas; } } diff --git a/libevm/VM.cpp b/libevm/VM.cpp index e0b487c9b..9f2fa6874 100644 --- a/libevm/VM.cpp +++ b/libevm/VM.cpp @@ -82,13 +82,19 @@ bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _steps) BOOST_THROW_EXCEPTION(BadInstruction()); // FEES... - bigint runGas = c_tierStepGas[metric.gasPriceTier]; + bigint runGas; bigint newTempSize = m_temp.size(); bigint copySize = 0; // should work, but just seems to result in immediate errorless exit on initial execution. yeah. weird. //m_onFail = std::function(onOperation); + auto metric = c_metrics[(int)inst]; + int gasPriceTier = metric.gasPriceTier; + if (gasPriceTier == InvalidTier) + BOOST_THROW_EXCEPTION(BadInstruction()); + else + runGas = c_tierStepGas[metric.gasPriceTier]; require(metric.args); auto onOperation = [&]() @@ -145,10 +151,6 @@ bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _steps) newTempSize = memNeed(m_stack[m_stack.size() - 2], m_stack[m_stack.size() - 4]); break; - case Instruction::JUMPDEST: - runGas = 1; - break; - case Instruction::LOG0: case Instruction::LOG1: case Instruction::LOG2: @@ -164,7 +166,7 @@ bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _steps) case Instruction::CALL: case Instruction::CALLCODE: runGas = (bigint)c_callGas + m_stack[m_stack.size() - 1]; - if (inst != Instruction::CALLCODE && !_ext.exists(asAddress(m_stack[m_stack.size() - 2]))) + if (!_ext.exists(asAddress(m_stack[m_stack.size() - 2]))) runGas += c_callNewAccountGas; if (m_stack[m_stack.size() - 3] > 0) runGas += c_callValueTransferGas; diff --git a/libevmcore/Instruction.cpp b/libevmcore/Instruction.cpp index 23f19ac94..eba075a4d 100644 --- a/libevmcore/Instruction.cpp +++ b/libevmcore/Instruction.cpp @@ -217,7 +217,7 @@ static const std::map c_instructionInfo = { Instruction::PC, { "PC", 0, 0, 1, false, BaseTier } }, { Instruction::MSIZE, { "MSIZE", 0, 0, 1, false, BaseTier } }, { Instruction::GAS, { "GAS", 0, 0, 1, false, BaseTier } }, - { Instruction::JUMPDEST, { "JUMPDEST", 0, 0, 0, true, SpecialTier } }, + { Instruction::JUMPDEST, { "JUMPDEST", 0, 1, 0, true, SpecialTier } }, { Instruction::PUSH1, { "PUSH1", 1, 0, 1, false, VeryLowTier } }, { Instruction::PUSH2, { "PUSH2", 2, 0, 1, false, VeryLowTier } }, { Instruction::PUSH3, { "PUSH3", 3, 0, 1, false, VeryLowTier } },