From d9bdfe5b4dd7a81d0a37c138cf80ae1b38f6a87e Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 28 Nov 2014 14:22:50 +0100 Subject: [PATCH] Latest PoC-7 changes. --- alethzero/MainWin.cpp | 6 +++--- eth/main.cpp | 6 +++--- libethereum/Executive.cpp | 7 ++++--- libethereum/Interface.h | 2 +- libevm/FeeStructure.cpp | 4 +++- libevm/FeeStructure.h | 4 +++- libevm/VM.h | 5 +++++ neth/main.cpp | 10 +++++----- 8 files changed, 27 insertions(+), 17 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index d4a122732..fc27d6e30 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -1664,7 +1664,7 @@ void Main::on_data_textChanged() errs.append("
" + QString::fromStdString(i).toHtmlEscaped() + "
"); } ui->code->setHtml(errs + lll + solidity + "

Code

" + QString::fromStdString(disassemble(m_data)).toHtmlEscaped()); - ui->gas->setMinimum((qint64)Client::txGas(m_data.size(), 0)); + ui->gas->setMinimum((qint64)Client::txGas(m_data, 0)); if (!ui->gas->isEnabled()) ui->gas->setValue(m_backupGas); ui->gas->setEnabled(true); @@ -1675,7 +1675,7 @@ void Main::on_data_textChanged() ui->code->setHtml(QString::fromStdString(dev::memDump(m_data, 8, true))); if (ethereum()->codeAt(fromString(ui->destination->currentText()), 0).size()) { - ui->gas->setMinimum((qint64)Client::txGas(m_data.size(), 1)); + ui->gas->setMinimum((qint64)Client::txGas(m_data, 1)); if (!ui->gas->isEnabled()) ui->gas->setValue(m_backupGas); ui->gas->setEnabled(true); @@ -1684,7 +1684,7 @@ void Main::on_data_textChanged() { if (ui->gas->isEnabled()) m_backupGas = ui->gas->value(); - ui->gas->setValue((qint64)Client::txGas(m_data.size())); + ui->gas->setValue((qint64)Client::txGas(m_data)); ui->gas->setEnabled(false); } } diff --git a/eth/main.cpp b/eth/main.cpp index be1a4ae65..9b63e0643 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -492,7 +492,7 @@ int main(int argc, char** argv) cnote << ssbd.str(); int ssize = sechex.length(); int size = hexAddr.length(); - u256 minGas = (u256)Client::txGas(data.size(), 0); + u256 minGas = (u256)Client::txGas(data, 0); if (size < 40) { if (size > 0) @@ -557,7 +557,7 @@ int main(int argc, char** argv) auto h = bc.currentHash(); auto blockData = bc.block(h); BlockInfo info(blockData); - u256 minGas = (u256)Client::txGas(0, 0); + u256 minGas = (u256)Client::txGas(bytes(), 0); Address dest = h160(fromHex(hexAddr)); c->transact(us.secret(), amount, dest, bytes(), minGas); } @@ -596,7 +596,7 @@ int main(int argc, char** argv) cnote << "Init:"; cnote << ssc.str(); } - u256 minGas = (u256)Client::txGas(init.size(), 0); + u256 minGas = (u256)Client::txGas(init, 0); if (endowment < 0) cwarn << "Invalid endowment"; else if (gas < minGas) diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp index ac557e198..6a123875c 100644 --- a/libethereum/Executive.cpp +++ b/libethereum/Executive.cpp @@ -22,6 +22,7 @@ #include #include #include +#include "Interface.h" #include "Executive.h" #include "State.h" #include "ExtVM.h" @@ -59,7 +60,7 @@ bool Executive::setup(bytesConstRef _rlp) } // Check gas cost is enough. - u256 gasCost = m_t.data().size() * c_txDataGas + c_txGas; + auto gasCost = Interface::txGas(m_t.data()); if (m_t.gas() < gasCost) { @@ -99,9 +100,9 @@ bool Executive::setup(bytesConstRef _rlp) } if (m_t.isCreation()) - return create(m_sender, m_t.value(), m_t.gasPrice(), m_t.gas() - gasCost, &m_t.data(), m_sender); + return create(m_sender, m_t.value(), m_t.gasPrice(), m_t.gas() - (u256)gasCost, &m_t.data(), m_sender); else - return call(m_t.receiveAddress(), m_sender, m_t.value(), m_t.gasPrice(), bytesConstRef(&m_t.data()), m_t.gas() - gasCost, m_sender); + return call(m_t.receiveAddress(), m_sender, m_t.value(), m_t.gasPrice(), bytesConstRef(&m_t.data()), m_t.gas() - (u256)gasCost, m_sender); } bool Executive::call(Address _receiveAddress, Address _senderAddress, u256 _value, u256 _gasPrice, bytesConstRef _data, u256 _gas, Address _originAddress) diff --git a/libethereum/Interface.h b/libethereum/Interface.h index add9a1bda..d598e1f9b 100644 --- a/libethereum/Interface.h +++ b/libethereum/Interface.h @@ -128,7 +128,7 @@ public: virtual Addresses addresses(int _block) const = 0; /// Get the fee associated for a transaction with the given data. - static u256 txGas(unsigned _dataCount, u256 _gas = 0) { return c_txDataGas * _dataCount + c_txGas + _gas; } + template static bigint txGas(T const& _data, u256 _gas = 0) { bigint ret = c_txGas + _gas; for (auto i: _data) ret += i ? c_txDataNonZeroGas : c_txDataZeroGas; return ret; } /// Get the remaining gas limit in this block. virtual u256 gasLimitRemaining() const = 0; diff --git a/libevm/FeeStructure.cpp b/libevm/FeeStructure.cpp index 6d868cac5..59a5329bc 100644 --- a/libevm/FeeStructure.cpp +++ b/libevm/FeeStructure.cpp @@ -35,8 +35,10 @@ u256 const dev::eth::c_sstoreRefundGas = 100; u256 const dev::eth::c_createGas = 100; u256 const dev::eth::c_callGas = 20; u256 const dev::eth::c_memoryGas = 1; -u256 const dev::eth::c_txDataGas = 5; +u256 const dev::eth::c_txDataZeroGas = 1; +u256 const dev::eth::c_txDataNonZeroGas = 5; u256 const dev::eth::c_txGas = 500; u256 const dev::eth::c_logGas = 32; u256 const dev::eth::c_logDataGas = 1; u256 const dev::eth::c_logTopicGas = 32; +u256 const dev::eth::c_copyGas = 1; diff --git a/libevm/FeeStructure.h b/libevm/FeeStructure.h index e57f7ccf8..4f415da5d 100644 --- a/libevm/FeeStructure.h +++ b/libevm/FeeStructure.h @@ -38,11 +38,13 @@ extern u256 const c_sstoreRefundGas; ///< Refunded gas, once per SSTORE operatio extern u256 const c_createGas; ///< Once per CREATE operation & contract-creation transaction. extern u256 const c_callGas; ///< Once per CALL operation & message call transaction. 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_txDataGas; ///< Per byte of data attached to a 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_txGas; ///< Per transaction. NOTE: Not payable on data of calls between transactions. 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_copyGas; ///< Multiplied by the number of 32-byte words that are copied (round up) for any *COPY operation and added. } } diff --git a/libevm/VM.h b/libevm/VM.h index 425eab8c8..9d43d7177 100644 --- a/libevm/VM.h +++ b/libevm/VM.h @@ -131,6 +131,7 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con // FEES... bigint runGas = c_stepGas; bigint newTempSize = m_temp.size(); + bigint copySize = 0; auto onOperation = [&]() { @@ -193,14 +194,17 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con break; case Instruction::CALLDATACOPY: require(3); + copySize = m_stack[m_stack.size() - 3]; newTempSize = memNeed(m_stack.back(), m_stack[m_stack.size() - 3]); break; case Instruction::CODECOPY: require(3); + copySize = m_stack[m_stack.size() - 3]; newTempSize = memNeed(m_stack.back(), m_stack[m_stack.size() - 3]); break; case Instruction::EXTCODECOPY: require(4); + copySize = m_stack[m_stack.size() - 4]; newTempSize = memNeed(m_stack[m_stack.size() - 2], m_stack[m_stack.size() - 4]); break; @@ -365,6 +369,7 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con newTempSize = (newTempSize + 31) / 32 * 32; if (newTempSize > m_temp.size()) runGas += c_memoryGas * (newTempSize - m_temp.size()) / 32; + runGas += c_copyGas * (copySize + 31) / 32; onOperation(); // if (_onOp) diff --git a/neth/main.cpp b/neth/main.cpp index e3a27c1d8..cb6d35593 100644 --- a/neth/main.cpp +++ b/neth/main.cpp @@ -646,7 +646,7 @@ int main(int argc, char** argv) ssbd << bbd; cnote << ssbd.str(); int ssize = fields[4].length(); - u256 minGas = (u256)Client::txGas(data.size(), 0); + u256 minGas = (u256)Client::txGas(data, 0); if (size < 40) { if (size > 0) @@ -700,9 +700,9 @@ int main(int argc, char** argv) auto h = bc.currentHash(); auto blockData = bc.block(h); BlockInfo info(blockData); - u256 minGas = (u256)Client::txGas(0, 0); + u256 minGas = (u256)Client::txGas(bytes(), 0); Address dest = h160(fromHex(fields[0])); - c.transact(us.secret(), amount, dest, bytes(), minGas, 10 * dev::eth::szabo); + c.transact(us.secret(), amount, dest, bytes(), minGas); } } } @@ -761,14 +761,14 @@ int main(int argc, char** argv) cnote << "Init:"; cnote << ssc.str(); } - u256 minGas = (u256)Client::txGas(init.size(), 0); + u256 minGas = (u256)Client::txGas(init, 0); if (endowment < 0) cwarn << "Invalid endowment"; else if (gas < minGas) cwarn << "Minimum gas amount is" << minGas; else { - c.transact(us.secret(), endowment, init, gas, 10 * dev::eth::szabo); + c.transact(us.secret(), endowment, init, gas); } } }