Browse Source

Async transact gas determination.

cl-refactor
Gav Wood 10 years ago
parent
commit
0ff44bd15c
  1. 73
      alethzero/Transact.cpp
  2. 3
      alethzero/Transact.h
  3. 48
      alethzero/Transact.ui

73
alethzero/Transact.cpp

@ -106,7 +106,12 @@ bool Transact::isCreation() const
u256 Transact::fee() const u256 Transact::fee() const
{ {
return ui->gas->value() * gasPrice(); return gas() * gasPrice();
}
u256 Transact::gas() const
{
return ui->gas->value() == -1 ? m_upperBound : ui->gas->value();
} }
u256 Transact::value() const u256 Transact::value() const
@ -199,10 +204,10 @@ void Transact::on_copyUnsigned_clicked()
if (isCreation()) if (isCreation())
// If execution is a contract creation, add Natspec to // If execution is a contract creation, add Natspec to
// a local Natspec LEVELDB // a local Natspec LEVELDB
t = Transaction(value(), gasPrice(), ui->gas->value(), m_data, nonce); t = Transaction(value(), gasPrice(), gas(), m_data, nonce);
else else
// TODO: cache like m_data. // TODO: cache like m_data.
t = Transaction(value(), gasPrice(), ui->gas->value(), toAccount().first, m_data, nonce); t = Transaction(value(), gasPrice(), gas(), toAccount().first, m_data, nonce);
qApp->clipboard()->setText(QString::fromStdString(toHex(t.rlp()))); qApp->clipboard()->setText(QString::fromStdString(toHex(t.rlp())));
} }
@ -350,11 +355,11 @@ void Transact::timerEvent(QTimerEvent*)
else else
er = ethereum()->call(from, value(), to, m_data, mid, gasPrice(), PendingBlock, FudgeFactor::Lenient); er = ethereum()->call(from, value(), to, m_data, mid, gasPrice(), PendingBlock, FudgeFactor::Lenient);
if (er.excepted == TransactionException::OutOfGas || er.excepted == TransactionException::OutOfGasBase || er.excepted == TransactionException::OutOfGasIntrinsic || er.codeDeposit == CodeDeposit::Failed) if (er.excepted == TransactionException::OutOfGas || er.excepted == TransactionException::OutOfGasBase || er.excepted == TransactionException::OutOfGasIntrinsic || er.codeDeposit == CodeDeposit::Failed)
m_lowerBound = mid; m_lowerBound = m_lowerBound == mid ? m_upperBound : mid;
else else
{ {
m_lastGood = er; m_lastGood = er;
m_upperBound = mid; m_upperBound = m_upperBound == mid ? m_lowerBound : mid;
} }
updateBounds(); updateBounds();
@ -371,58 +376,52 @@ void Transact::updateBounds()
double nran = m_upperBound - m_lowerBound; double nran = m_upperBound - m_lowerBound;
int x = int(log2(oran / nran) * 100.0 / log2(oran * 2)); int x = int(log2(oran / nran) * 100.0 / log2(oran * 2));
ui->progressGas->setValue(x); ui->progressGas->setValue(x);
ui->progressGas->setVisible(true);
ui->gas->setSpecialValueText(QString("Auto (%1 gas)").arg(m_upperBound));
} }
void Transact::finaliseBounds() void Transact::finaliseBounds()
{ {
qint64 baseGas = (qint64)Transaction::gasRequired(m_data, 0); quint64 baseGas = (quint64)Transaction::gasRequired(m_data, 0);
GasRequirements gasReq = GasRequirements{m_upperBound, baseGas, m_upperBound - baseGas, (qint64)m_lastGood.gasRefunded, m_lastGood}; ui->progressGas->setVisible(false);
QString htmlInfo = QString("<div class=\"info\"><span class=\"icon\">INFO</span> Gas required: %1 total = %2 base, %3 exec [%4 refunded later]</div>").arg(gasReq.neededGas).arg(gasReq.baseGas).arg(gasReq.executionGas).arg(gasReq.refundedGas); quint64 executionGas = m_upperBound - baseGas;
QString htmlInfo = QString("<div class=\"info\"><span class=\"icon\">INFO</span> Gas required: %1 total = %2 base, %3 exec [%4 refunded later]</div>").arg(m_upperBound).arg(baseGas).arg(executionGas).arg((qint64)m_lastGood.gasRefunded);
auto bail = [&](QString he) { auto bail = [&](QString he) {
m_allGood = false; ui->send->setEnabled(false);
// ui->send->setEnabled(false); ui->code->setHtml(he + htmlInfo + m_dataInfo);
ui->code->setHtml(he + htmlInfo + ui->code->toHtml());
}; };
auto s = fromAccount(); auto s = fromAccount();
auto b = ethereum()->balanceAt(s, PendingBlock); auto b = ethereum()->balanceAt(s, PendingBlock);
if (b < value() + gasReq.baseGas * gasPrice()) if (b < value() + baseGas * gasPrice())
{ {
// Not enough - bail. // Not enough - bail.
bail("<div class=\"error\"><span class=\"icon\">ERROR</span> Account doesn't contain enough for paying even the basic amount of gas required.</div>"); bail("<div class=\"error\"><span class=\"icon\">ERROR</span> Account doesn't contain enough for paying even the basic amount of gas required.</div>");
return; return;
} }
if (gasReq.neededGas > m_ethereum->gasLimitRemaining()) if (m_upperBound > m_ethereum->gasLimitRemaining())
{ {
// Not enough - bail. // Not enough - bail.
bail("<div class=\"error\"><span class=\"icon\">ERROR</span> Gas remaining in block isn't enough to allow the gas required.</div>"); bail("<div class=\"error\"><span class=\"icon\">ERROR</span> Gas remaining in block isn't enough to allow the gas required.</div>");
return; return;
} }
if (gasReq.er.excepted != TransactionException::None) if (m_lastGood.excepted != TransactionException::None)
{ {
bail("<div class=\"error\"><span class=\"icon\">ERROR</span> " + QString::fromStdString(toString(gasReq.er.excepted)) + "</div>"); bail("<div class=\"error\"><span class=\"icon\">ERROR</span> " + QString::fromStdString(toString(m_lastGood.excepted)) + "</div>");
return; return;
} }
if (gasReq.er.codeDeposit == CodeDeposit::Failed) if (m_lastGood.codeDeposit == CodeDeposit::Failed)
{ {
bail("<div class=\"error\"><span class=\"icon\">ERROR</span> Code deposit failed due to insufficient gas; " + QString::fromStdString(toString(gasReq.er.gasForDeposit)) + " GAS &lt; " + QString::fromStdString(toString(gasReq.er.depositSize)) + " bytes * " + QString::fromStdString(toString(c_createDataGas)) + "GAS/byte</div>"); bail("<div class=\"error\"><span class=\"icon\">ERROR</span> Code deposit failed due to insufficient gas; " + QString::fromStdString(toString(m_lastGood.gasForDeposit)) + " GAS &lt; " + QString::fromStdString(toString(m_lastGood.depositSize)) + " bytes * " + QString::fromStdString(toString(c_createDataGas)) + "GAS/byte</div>");
return; return;
} }
// Update gas
if (ui->gas->value() == ui->gas->minimum())
{
ui->gas->setMinimum(gasReq.neededGas);
ui->gas->setValue(gasReq.neededGas);
}
else
ui->gas->setMinimum(gasReq.neededGas);
updateFee(); updateFee();
ui->code->setHtml(htmlInfo + ui->code->toHtml()); ui->code->setHtml(htmlInfo + m_dataInfo);
ui->send->setEnabled(true);
killTimer(m_gasCalcTimer); killTimer(m_gasCalcTimer);
} }
@ -473,13 +472,12 @@ void Transact::rejigData()
if (!s) if (!s)
return; return;
m_allGood = true;
QString htmlInfo; QString htmlInfo;
auto bail = [&](QString he) { auto bail = [&](QString he) {
m_allGood = false; ui->send->setEnabled(false);
// ui->send->setEnabled(false); m_dataInfo = he + htmlInfo;
ui->code->setHtml(he + htmlInfo); ui->code->setHtml(m_dataInfo);
}; };
// Determine m_info. // Determine m_info.
@ -513,8 +511,9 @@ void Transact::rejigData()
determineGasRequirements(); determineGasRequirements();
ui->code->setHtml(htmlInfo); m_dataInfo = htmlInfo;
// ui->send->setEnabled(m_allGood); ui->code->setHtml(m_dataInfo);
ui->send->setEnabled(true);
} }
Secret Transact::findSecret(u256 _totalReq) const Secret Transact::findSecret(u256 _totalReq) const
@ -576,7 +575,7 @@ void Transact::on_send_clicked()
{ {
// If execution is a contract creation, add Natspec to // If execution is a contract creation, add Natspec to
// a local Natspec LEVELDB // a local Natspec LEVELDB
ethereum()->submitTransaction(s, value(), m_data, ui->gas->value(), gasPrice(), nonce); ethereum()->submitTransaction(s, value(), m_data, gas(), gasPrice(), nonce);
#if ETH_SOLIDITY #if ETH_SOLIDITY
string src = ui->data->toPlainText().toStdString(); string src = ui->data->toPlainText().toStdString();
if (sourceIsSolidity(src)) if (sourceIsSolidity(src))
@ -595,7 +594,7 @@ void Transact::on_send_clicked()
} }
else else
// TODO: cache like m_data. // TODO: cache like m_data.
ethereum()->submitTransaction(s, value(), toAccount().first, m_data, ui->gas->value(), gasPrice(), nonce); ethereum()->submitTransaction(s, value(), toAccount().first, m_data, gas(), gasPrice(), nonce);
close(); close();
} }
@ -614,8 +613,8 @@ void Transact::on_debug_clicked()
{ {
Block postState(ethereum()->postState()); Block postState(ethereum()->postState());
Transaction t = isCreation() ? Transaction t = isCreation() ?
Transaction(value(), gasPrice(), ui->gas->value(), m_data, postState.transactionsFrom(from)) : Transaction(value(), gasPrice(), gas(), m_data, postState.transactionsFrom(from)) :
Transaction(value(), gasPrice(), ui->gas->value(), toAccount().first, m_data, postState.transactionsFrom(from)); Transaction(value(), gasPrice(), gas(), toAccount().first, m_data, postState.transactionsFrom(from));
t.forceSender(from); t.forceSender(from);
Debugger dw(m_main, this); Debugger dw(m_main, this);
Executive e(postState, ethereum()->blockChain(), 0); Executive e(postState, ethereum()->blockChain(), 0);

3
alethzero/Transact.h

@ -88,6 +88,7 @@ private:
void updateFee(); void updateFee();
bool isCreation() const; bool isCreation() const;
dev::u256 fee() const; dev::u256 fee() const;
dev::u256 gas() const;
dev::u256 total() const; dev::u256 total() const;
dev::u256 value() const; dev::u256 value() const;
dev::u256 gasPrice() const; dev::u256 gasPrice() const;
@ -108,8 +109,8 @@ private:
dev::eth::Client* m_ethereum = nullptr; dev::eth::Client* m_ethereum = nullptr;
MainFace* m_main = nullptr; MainFace* m_main = nullptr;
NatSpecFace* m_natSpecDB = nullptr; NatSpecFace* m_natSpecDB = nullptr;
bool m_allGood = false;
QString m_dataInfo;
qint64 m_startLowerBound = 0; qint64 m_startLowerBound = 0;
qint64 m_startUpperBound = 0; qint64 m_startUpperBound = 0;
qint64 m_lowerBound = 0; qint64 m_lowerBound = 0;

48
alethzero/Transact.ui

@ -6,7 +6,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>543</width> <width>604</width>
<height>695</height> <height>695</height>
</rect> </rect>
</property> </property>
@ -23,17 +23,20 @@
</item> </item>
<item row="4" column="1"> <item row="4" column="1">
<widget class="QSpinBox" name="gas"> <widget class="QSpinBox" name="gas">
<property name="specialValueText">
<string>Automatic</string>
</property>
<property name="suffix"> <property name="suffix">
<string> gas</string> <string> gas</string>
</property> </property>
<property name="minimum"> <property name="minimum">
<number>1</number> <number>-1</number>
</property> </property>
<property name="maximum"> <property name="maximum">
<number>430000000</number> <number>430000000</number>
</property> </property>
<property name="value"> <property name="value">
<number>10000</number> <number>-1</number>
</property> </property>
</widget> </widget>
</item> </item>
@ -261,7 +264,20 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="1"> <item row="5" column="3">
<widget class="QSpinBox" name="maxGas">
<property name="suffix">
<string> gas</string>
</property>
<property name="prefix">
<string>max </string>
</property>
<property name="maximum">
<number>450000000</number>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QSpinBox" name="minGas"> <widget class="QSpinBox" name="minGas">
<property name="readOnly"> <property name="readOnly">
<bool>true</bool> <bool>true</bool>
@ -272,10 +288,22 @@
<property name="prefix"> <property name="prefix">
<string>min </string> <string>min </string>
</property> </property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>450000000</number>
</property>
</widget> </widget>
</item> </item>
<item row="6" column="3"> <item row="5" column="1">
<widget class="QProgressBar" name="progressGas"> <widget class="QProgressBar" name="progressGas">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="value"> <property name="value">
<number>24</number> <number>24</number>
</property> </property>
@ -284,16 +312,6 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="2">
<widget class="QSpinBox" name="maxGas">
<property name="suffix">
<string> gas</string>
</property>
<property name="prefix">
<string>max </string>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
<resources/> <resources/>

Loading…
Cancel
Save