Browse Source

Various fixes for PoC-4 (né 3.5)

cl-refactor
Gav Wood 11 years ago
parent
commit
153c7c36cb
  1. 171
      alethzero/Main.ui
  2. 46
      alethzero/MainWin.cpp
  3. 3
      libethereum/CommonData.cpp
  4. 1
      libethereum/Exceptions.h
  5. 50
      libethereum/State.cpp
  6. 3
      libethereum/Transaction.cpp

171
alethzero/Main.ui

@ -390,45 +390,22 @@
</attribute> </attribute>
<widget class="QWidget" name="dockWidgetContents_5"> <widget class="QWidget" name="dockWidgetContents_5">
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<item row="0" column="0"> <item row="4" column="0">
<widget class="QLabel" name="label5"> <widget class="QLabel" name="label_2">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="text"> <property name="text">
<string>&amp;To</string> <string>&amp;Data</string>
</property>
<property name="buddy">
<cstring>destination</cstring>
</property>
</widget>
</item>
<item row="0" column="1" colspan="4">
<widget class="QLineEdit" name="destination">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="placeholderText">
<string>(Create Contract)</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="4">
<widget class="QLineEdit" name="calculatedName">
<property name="enabled">
<bool>false</bool>
</property> </property>
<property name="readOnly"> <property name="alignment">
<bool>true</bool> <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property> </property>
<property name="placeholderText"> <property name="buddy">
<string/> <cstring>data</cstring>
</property> </property>
</widget> </widget>
</item> </item>
@ -442,7 +419,10 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="1" colspan="3"> <item row="3" column="3">
<widget class="QComboBox" name="gasPriceUnits"/>
</item>
<item row="2" column="1" colspan="2">
<widget class="QSpinBox" name="value"> <widget class="QSpinBox" name="value">
<property name="suffix"> <property name="suffix">
<string/> <string/>
@ -455,21 +435,43 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="4"> <item row="0" column="0">
<widget class="QComboBox" name="valueUnits"/> <widget class="QLabel" name="label5">
</item> <property name="sizePolicy">
<item row="3" column="0"> <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<widget class="QLabel" name="label_6"> <horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text"> <property name="text">
<string>&amp;Gas</string> <string>&amp;To</string>
</property> </property>
<property name="buddy"> <property name="buddy">
<cstring>gas</cstring> <cstring>destination</cstring>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="1"> <item row="5" column="0" colspan="4">
<widget class="QSpinBox" name="gas"> <widget class="QSplitter" name="splitter_5">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<widget class="QPlainTextEdit" name="data"/>
<widget class="QPlainTextEdit" name="code">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</widget>
</item>
<item row="3" column="2">
<widget class="QSpinBox" name="gasPrice">
<property name="prefix">
<string>@ </string>
</property>
<property name="minimum"> <property name="minimum">
<number>1</number> <number>1</number>
</property> </property>
@ -478,21 +480,11 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="2"> <item row="3" column="1">
<widget class="QLabel" name="label_7"> <widget class="QSpinBox" name="gas">
<property name="sizePolicy"> <property name="suffix">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred"> <string> gas</string>
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>at</string>
</property> </property>
</widget>
</item>
<item row="3" column="3">
<widget class="QSpinBox" name="gasPrice">
<property name="minimum"> <property name="minimum">
<number>1</number> <number>1</number>
</property> </property>
@ -501,29 +493,20 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="4"> <item row="2" column="3">
<widget class="QComboBox" name="gasPriceUnits"/> <widget class="QComboBox" name="valueUnits"/>
</item> </item>
<item row="4" column="0"> <item row="3" column="0">
<widget class="QLabel" name="label_2"> <widget class="QLabel" name="label_6">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text"> <property name="text">
<string>&amp;Data</string> <string>&amp;Gas</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property> </property>
<property name="buddy"> <property name="buddy">
<cstring>data</cstring> <cstring>gas</cstring>
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="1" colspan="4"> <item row="4" column="1" colspan="3">
<widget class="QLabel" name="fee"> <widget class="QLabel" name="fee">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
@ -539,23 +522,14 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="5" column="0" colspan="5"> <item row="6" column="3">
<widget class="QSplitter" name="splitter_5"> <widget class="QPushButton" name="send">
<property name="orientation"> <property name="text">
<enum>Qt::Vertical</enum> <string>&amp;Send</string>
</property> </property>
<widget class="QPlainTextEdit" name="data"/>
<widget class="QPlainTextEdit" name="code">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</widget> </widget>
</item> </item>
<item row="6" column="0" colspan="4"> <item row="6" column="0" colspan="3">
<widget class="QLabel" name="total"> <widget class="QLabel" name="total">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
@ -568,10 +542,29 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="4"> <item row="1" column="1" colspan="3">
<widget class="QPushButton" name="send"> <widget class="QLineEdit" name="calculatedName">
<property name="text"> <property name="enabled">
<string>&amp;Send</string> <bool>false</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
<property name="placeholderText">
<string/>
</property>
</widget>
</item>
<item row="0" column="1" colspan="3">
<widget class="QLineEdit" name="destination">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="placeholderText">
<string>(Create Contract)</string>
</property> </property>
</widget> </widget>
</item> </item>

46
alethzero/MainWin.cpp

@ -81,6 +81,8 @@ Main::Main(QWidget *parent) :
int pocnumber = QString(ETH_QUOTED(ETH_VERSION)).section('.', 1, 1).toInt(); int pocnumber = QString(ETH_QUOTED(ETH_VERSION)).section('.', 1, 1).toInt();
if (pocnumber == 3) if (pocnumber == 3)
m_servers.push_back("54.201.28.117:30303"); m_servers.push_back("54.201.28.117:30303");
else if (pocnumber == 4)
m_servers.push_back("54.72.31.55:30303");
else else
{ {
connect(&m_webCtrl, &QNetworkAccessManager::finished, [&](QNetworkReply* _r) connect(&m_webCtrl, &QNetworkAccessManager::finished, [&](QNetworkReply* _r)
@ -393,23 +395,21 @@ void Main::on_blocks_currentItemChanged()
s << "<h4>" << h << "[<b>" << txi << "</b>]</h4>"; s << "<h4>" << h << "[<b>" << txi << "</b>]</h4>";
auto ss = tx.safeSender(); auto ss = tx.safeSender();
s << "<br/>From: <b>" << pretty(ss).toStdString() << "</b> " << ss; s << "<br/>From: <b>" << pretty(ss).toStdString() << "</b> " << ss;
if (tx.receiveAddress) if (tx.isCreation)
s << "<br/>To: <b>" << pretty(tx.receiveAddress).toStdString() << "</b> " << tx.receiveAddress;
else
s << "<br/>Creates: <b>" << pretty(right160(th)).toStdString() << "</b> " << right160(th); s << "<br/>Creates: <b>" << pretty(right160(th)).toStdString() << "</b> " << right160(th);
else
s << "<br/>To: <b>" << pretty(tx.receiveAddress).toStdString() << "</b> " << tx.receiveAddress;
s << "<br/>Value: <b>" << formatBalance(tx.value) << "</b>"; s << "<br/>Value: <b>" << formatBalance(tx.value) << "</b>";
s << "<br/>Gas: <b>" << tx.gas << "</b>";
s << "<br/>Gas price: <b>" << tx.gasPrice << "</b>";
s << "&nbsp;&emsp;&nbsp;#<b>" << tx.nonce << "</b>"; s << "&nbsp;&emsp;&nbsp;#<b>" << tx.nonce << "</b>";
if (tx.storage.size() && tx.isCreation) s << "<br/>Gas price: <b>" << formatBalance(tx.gasPrice) << "</b>";
if (tx.isCreation)
{ {
s << "<br/>Storage:&nbsp;&emsp;&nbsp;"; s << "<br/>Storage:&nbsp;&emsp;&nbsp;";
// for (auto i: tx.data)
// s << "0x<b>" << hex << i << "</b>&emsp;";
s << "</br>" << disassemble(tx.storage); s << "</br>" << disassemble(tx.storage);
} }
else if (tx.data.size() && !tx.isCreation) else
{ {
s << "<br/>Gas: <b>" << tx.gas << "</b>";
s << "<br/>Data:&nbsp;&emsp;&nbsp; 0x..." << setw(2) << setfill('0') << hex; s << "<br/>Data:&nbsp;&emsp;&nbsp; 0x..." << setw(2) << setfill('0') << hex;
unsigned c = 0; unsigned c = 0;
for (auto i: tx.data) for (auto i: tx.data)
@ -438,7 +438,7 @@ void Main::on_contracts_currentItemChanged()
u256 next = 0; u256 next = 0;
unsigned numerics = 0; unsigned numerics = 0;
bool unexpectedNumeric = false; bool unexpectedNumeric = false;
for (auto i: mem) for (auto const& i: mem)
{ {
if (next < i.first) if (next < i.first)
{ {
@ -451,9 +451,7 @@ void Main::on_contracts_currentItemChanged()
s << " ...<br/>@" << showbase << hex << i.first << "&nbsp;&nbsp;&nbsp;&nbsp;"; s << " ...<br/>@" << showbase << hex << i.first << "&nbsp;&nbsp;&nbsp;&nbsp;";
} }
else if (!next) else if (!next)
{
s << "@" << showbase << hex << i.first << "&nbsp;&nbsp;&nbsp;&nbsp;"; s << "@" << showbase << hex << i.first << "&nbsp;&nbsp;&nbsp;&nbsp;";
}
auto iit = c_instructionInfo.find((Instruction)(unsigned)i.second); auto iit = c_instructionInfo.find((Instruction)(unsigned)i.second);
if (numerics || iit == c_instructionInfo.end() || (u256)(unsigned)iit->first != i.second) // not an instruction or expecting an argument... if (numerics || iit == c_instructionInfo.end() || (u256)(unsigned)iit->first != i.second) // not an instruction or expecting an argument...
{ {
@ -534,21 +532,35 @@ void Main::on_data_textChanged()
else else
{ {
string code = ui->data->toPlainText().replace(" ", "").toStdString(); string code = ui->data->toPlainText().replace(" ", "").toStdString();
m_data = fromHex(code); try
{
m_data = fromHex(code);
}
catch (...)
{}
ui->code->setPlainText(QString::fromStdString(toHex(m_data))); ui->code->setPlainText(QString::fromStdString(toHex(m_data)));
ui->gas->setEnabled(true); if (m_client->postState().isContractAddress(fromString(ui->destination->text())))
{
ui->gas->setMinimum((qint64)state().callGas(m_data.size(), 1));
ui->gas->setEnabled(true);
}
else
{
ui->gas->setValue((qint64)state().callGas(m_data.size()));
ui->gas->setEnabled(false);
}
} }
updateFee(); updateFee();
} }
bool Main::isCreation() const bool Main::isCreation() const
{ {
return !(ui->destination->text().isEmpty() || !ui->destination->text().toInt()); return ui->destination->text().isEmpty()/* || !ui->destination->text().toInt()*/;
} }
u256 Main::fee() const u256 Main::fee() const
{ {
return (isCreation() ? state().createGas(m_storage.size()) : state().callGas(m_data.size(), ui->gas->value())) * gasPrice(); return ui->gas->value() * gasPrice();
} }
u256 Main::value() const u256 Main::value() const
@ -568,7 +580,7 @@ u256 Main::total() const
void Main::updateFee() void Main::updateFee()
{ {
ui->fee->setText(QString("(fee: %1)").arg(formatBalance(fee()).c_str())); ui->fee->setText(QString("(gas sub-total: %1)").arg(formatBalance(fee()).c_str()));
auto totalReq = total(); auto totalReq = total();
ui->total->setText(QString("Total: %1").arg(formatBalance(totalReq).c_str())); ui->total->setText(QString("Total: %1").arg(formatBalance(totalReq).c_str()));

3
libethereum/CommonData.cpp

@ -72,8 +72,7 @@ int eth::fromHex(char _i)
bytes eth::fromHex(std::string const& _s) bytes eth::fromHex(std::string const& _s)
{ {
assert(_s.size() % 2 == 0); if (_s.size() % 2 || _s.size() < 2)
if (_s.size() < 2)
return bytes(); return bytes();
uint s = (_s[0] == '0' && _s[1] == 'x') ? 2 : 0; uint s = (_s[0] == '0' && _s[1] == 'x') ? 2 : 0;
std::vector<uint8_t> ret; std::vector<uint8_t> ret;

1
libethereum/Exceptions.h

@ -30,6 +30,7 @@ class OutOfGas: public VMException {};
class StackTooSmall: public VMException { public: StackTooSmall(u256 _req, u256 _got): req(_req), got(_got) {} u256 req; u256 got; }; class StackTooSmall: public VMException { public: StackTooSmall(u256 _req, u256 _got): req(_req), got(_got) {} u256 req; u256 got; };
class OperandOutOfRange: public VMException { public: OperandOutOfRange(u256 _min, u256 _max, u256 _got): mn(_min), mx(_max), got(_got) {} u256 mn; u256 mx; u256 got; }; class OperandOutOfRange: public VMException { public: OperandOutOfRange(u256 _min, u256 _max, u256 _got): mn(_min), mx(_max), got(_got) {} u256 mn; u256 mx; u256 got; };
class GasPriceTooLow: public Exception {};
class NoSuchContract: public Exception {}; class NoSuchContract: public Exception {};
class ContractAddressCollision: public Exception {}; class ContractAddressCollision: public Exception {};
class FeeTooSmall: public Exception {}; class FeeTooSmall: public Exception {};

50
libethereum/State.cpp

@ -608,6 +608,13 @@ void State::execute(bytesConstRef _rlp)
throw InvalidNonce(nonceReq, t.nonce); throw InvalidNonce(nonceReq, t.nonce);
} }
// Don't like transactions whose gas price is too low.
if (t.gasPrice < 10 * szabo)
{
clog(StateChat) << "Offered gas-price is too low.";
throw GasPriceTooLow();
}
// Entry point for a contract-originated transaction. // Entry point for a contract-originated transaction.
u256 gasCost; u256 gasCost;
if (t.isCreation) if (t.isCreation)
@ -617,10 +624,19 @@ void State::execute(bytesConstRef _rlp)
if (i) if (i)
nonZero++; nonZero++;
gasCost = nonZero * c_sstoreGas + c_createGas; gasCost = nonZero * c_sstoreGas + c_createGas;
t.gas = gasCost;
} }
else else
gasCost = t.data.size() * c_txDataGas + c_callGas + t.gas; {
u256 cost = t.value + gasCost * t.gasPrice; gasCost = t.data.size() * c_txDataGas + c_callGas;
if (t.gas < gasCost)
{
clog(StateChat) << "Not enough gas to pay for the transaction.";
throw OutOfGas();
}
}
u256 cost = t.value + t.gas * t.gasPrice;
// Avoid unaffordable transactions. // Avoid unaffordable transactions.
if (balance(sender) < cost) if (balance(sender) < cost)
@ -629,42 +645,40 @@ void State::execute(bytesConstRef _rlp)
throw NotEnoughCash(); throw NotEnoughCash();
} }
u256 gas = t.gas - gasCost;
// Increment associated nonce for sender.
noteSending(sender);
// Pay...
cnote << "Paying" << formatBalance(cost) << "from sender (includes" << t.gas << "gas at" << formatBalance(t.gasPrice) << ")";
subBalance(sender, cost);
if (t.isCreation) if (t.isCreation)
{ {
Address newAddress = right160(t.sha3()); Address newAddress = right160(t.sha3());
while (isContractAddress(newAddress) || isNormalAddress(newAddress)) while (isContractAddress(newAddress) || isNormalAddress(newAddress))
newAddress = (u160)newAddress + 1; newAddress = (u160)newAddress + 1;
// Increment associated nonce for sender.
noteSending(sender);
// Pay out of sender...
subBalance(sender, cost);
// Set up new account... // Set up new account...
m_cache[newAddress] = AddressState(t.value, 0, AddressType::Contract); m_cache[newAddress] = AddressState(t.value, 0, AddressType::Contract);
auto& mem = m_cache[newAddress].memory(); auto& mem = m_cache[newAddress].memory();
for (uint i = 0; i < t.data.size(); ++i) for (uint i = 0; i < t.storage.size(); ++i)
mem[i] = t.storage[i]; mem[i] = t.storage[i];
} }
else else
{ {
// Increment associated nonce for sender. cnote << "Giving" << formatBalance(t.value) << "to receiver";
noteSending(sender);
// Pay...
subBalance(sender, cost);
addBalance(t.receiveAddress, t.value); addBalance(t.receiveAddress, t.value);
u256 gas = t.gas;
if (isContractAddress(t.receiveAddress)) if (isContractAddress(t.receiveAddress))
// Once we get here, there's no going back. // Once we get here, there's no going back.
call(t.receiveAddress, sender, t.value, t.gasPrice, bytesConstRef(&t.data), &gas, bytesRef()); call(t.receiveAddress, sender, t.value, t.gasPrice, bytesConstRef(&t.data), &gas, bytesRef());
addBalance(t.receiveAddress, gas * t.gasPrice);
} }
cnote << "Refunding" << formatBalance(gas * t.gasPrice) << "to sender (=" << gas << "*" << formatBalance(t.gasPrice) << ")";
addBalance(sender, gas * t.gasPrice);
// Add to the user-originated transactions that we've executed. // Add to the user-originated transactions that we've executed.
// NOTE: Here, contract-originated transactions will not get added to the transaction list. // NOTE: Here, contract-originated transactions will not get added to the transaction list.
// If this is wrong, move this line into execute(Transaction const& _t, Address _sender) and // If this is wrong, move this line into execute(Transaction const& _t, Address _sender) and

3
libethereum/Transaction.cpp

@ -44,6 +44,7 @@ Transaction::Transaction(bytesConstRef _rlpData)
storage.reserve(rlp[field = 3].itemCountStrict()); storage.reserve(rlp[field = 3].itemCountStrict());
for (auto const& i: rlp[3]) for (auto const& i: rlp[3])
storage.push_back(i.toInt<u256>()); storage.push_back(i.toInt<u256>());
vrs = Signature{ rlp[field = 4].toInt<byte>(), rlp[field = 5].toInt<u256>(), rlp[field = 6].toInt<u256>() };
} }
else else
{ {
@ -52,8 +53,8 @@ Transaction::Transaction(bytesConstRef _rlpData)
data.reserve(rlp[field = 5].itemCountStrict()); data.reserve(rlp[field = 5].itemCountStrict());
for (auto const& i: rlp[5]) for (auto const& i: rlp[5])
data.push_back(i.toInt<byte>()); data.push_back(i.toInt<byte>());
vrs = Signature{ rlp[field = 6].toInt<byte>(), rlp[field = 7].toInt<u256>(), rlp[field = 8].toInt<u256>() };
} }
vrs = Signature{ rlp[field = 6].toInt<byte>(), rlp[field = 7].toInt<u256>(), rlp[field = 8].toInt<u256>() };
} }
catch (RLPException const&) catch (RLPException const&)
{ {

Loading…
Cancel
Save