Browse Source

AZ transact auto-gas determination.

cl-refactor
Gav Wood 10 years ago
parent
commit
aadf3998d9
  1. 87
      alethzero/Transact.cpp

87
alethzero/Transact.cpp

@ -163,6 +163,25 @@ void Transact::on_destination_currentTextChanged(QString)
// updateFee();
}
static std::string toString(TransactionException _te)
{
switch (_te)
{
case TransactionException::Unknown: return "Unknown error";
case TransactionException::InvalidSignature: return "Permanent Abort: Invalid transaction signature";
case TransactionException::InvalidNonce: return "Transient Abort: Invalid transaction nonce";
case TransactionException::NotEnoughCash: return "Transient Abort: Not enough cash to pay for transaction";
case TransactionException::OutOfGasBase: return "Permanent Abort: Not enough gas to consider transaction";
case TransactionException::BlockGasLimitReached: return "Transient Abort: Gas limit of block reached";
case TransactionException::BadInstruction: return "VM Error: Attempt to execute invalid instruction";
case TransactionException::BadJumpDestination: return "VM Error: Attempt to jump to invalid destination";
case TransactionException::OutOfGas: return "VM Error: Out of gas";
case TransactionException::OutOfStack: return "VM Error: VM stack limit reached during execution";
case TransactionException::StackUnderflow: return "VM Error: Stack underflow";
default:; return std::string();
}
}
void Transact::rejigData()
{
if (!ethereum())
@ -247,26 +266,11 @@ void Transact::rejigData()
{
ExecutionResult er = ethereum()->create(s, value(), m_data, ethereum()->gasLimitRemaining(), gasPrice());
gasNeeded = (qint64)er.gasUsed;
auto base = (qint64)Interface::txGas(m_data, 0);
errs += QString("<div class=\"info\"><span class=\"icon\">INFO</span> Gas required: %1 base, %2 init</div>").arg(base).arg((qint64)er.gasUsed - base);
if (er.excepted != TransactionException::None)
{
string exErr;
switch (er.excepted)
{
case TransactionException::Unknown: exErr = "Unknown error"; break;
case TransactionException::InvalidSignature: exErr = "Permanent Abort: Invalid transaction signature"; break;
case TransactionException::InvalidNonce: exErr = "Transient Abort: Invalid transaction nonce"; break;
case TransactionException::NotEnoughCash: exErr = "Transient Abort: Not enough cash to pay for transaction"; break;
case TransactionException::OutOfGasBase: exErr = "Permanent Abort: Not enough gas to consider transaction"; break;
case TransactionException::BlockGasLimitReached: exErr = "Transient Abort: Gas limit of block reached"; break;
case TransactionException::BadInstruction: exErr = "VM Error: Attempt to execute invalid instruction"; break;
case TransactionException::BadJumpDestination: exErr = "VM Error: Attempt to jump to invalid destination"; break;
case TransactionException::OutOfGas: exErr = "VM Error: Out of gas"; break;
case TransactionException::StackUnderflow: exErr = "VM Error: Stack underflow"; break;
default:;
}
errs += "<div class=\"error\"><span class=\"icon\">ERROR</span> " + QString::fromStdString(exErr) + "</div";
}
errs += "<div class=\"error\"><span class=\"icon\">ERROR</span> " + QString::fromStdString(toString(er.excepted)) + "</div>";
if (er.codeDeposit == CodeDeposit::Failed)
errs += "<div class=\"error\"><span class=\"icon\">ERROR</span> Code deposit failed due to insufficient gas</div>";
}
@ -277,18 +281,26 @@ void Transact::rejigData()
ui->code->setHtml(errs + lll + solidity + "<h4>Code</h4>" + QString::fromStdString(disassemble(m_data)).toHtmlEscaped() + "<h4>Hex</h4>" Div(Mono) + QString::fromStdString(toHex(m_data)) + "</div>");
if (ui->gas->value() == ui->gas->minimum())
{
ui->gas->setMinimum(gasNeeded);
if (!ui->gas->isEnabled())
ui->gas->setValue(m_backupGas);
ui->gas->setValue(gasNeeded);
}
else
ui->gas->setMinimum(gasNeeded);
// if (!ui->gas->isEnabled())
// ui->gas->setValue(m_backupGas);
ui->gas->setEnabled(true);
// if (ui->gas->value() == ui->gas->minimum() && !src.empty())
// ui->gas->setValue((int)(m_ethereum->postState().gasLimitRemaining() / 10));
}
else
{
auto base = (qint64)Interface::txGas(m_data, 0);
m_data = parseData(ui->data->toPlainText().toStdString());
auto to = m_context->fromString(ui->destination->currentText());
QString natspec;
QString errs;
if (ethereum()->codeAt(to, 0).size())
{
string userNotice = m_natSpecDB->getUserNotice(ethereum()->postState().codeHash(to), m_data);
@ -299,7 +311,35 @@ void Transact::rejigData()
NatspecExpressionEvaluator evaluator;
natspec = evaluator.evalExpression(QString::fromStdString(userNotice));
}
ui->gas->setMinimum((qint64)Interface::txGas(m_data, 1));
qint64 gasNeeded = 0;
if (true)
{
auto s = findSecret(value() + ethereum()->gasLimitRemaining() * gasPrice());
if (!s)
errs += "<div class=\"error\"><span class=\"icon\">ERROR</span> No single account contains enough gas.</div>";
// TODO: use account with most balance anyway.
else
{
ExecutionResult er = ethereum()->call(s, value(), to, m_data, ethereum()->gasLimitRemaining(), gasPrice());
gasNeeded = (qint64)er.gasUsed;
errs += QString("<div class=\"info\"><span class=\"icon\">INFO</span> Gas required: %1 base, %2 exec</div>").arg(base).arg((qint64)er.gasUsed - base);
if (er.excepted != TransactionException::None)
errs += "<div class=\"error\"><span class=\"icon\">ERROR</span> " + QString::fromStdString(toString(er.excepted)) + "</div>";
}
}
else
gasNeeded = (qint64)Interface::txGas(m_data, 0);
if (ui->gas->value() == ui->gas->minimum())
{
ui->gas->setMinimum(gasNeeded);
ui->gas->setValue(gasNeeded);
}
else
ui->gas->setMinimum(gasNeeded);
if (!ui->gas->isEnabled())
ui->gas->setValue(m_backupGas);
ui->gas->setEnabled(true);
@ -309,10 +349,11 @@ void Transact::rejigData()
natspec += "Destination not a contract.";
if (ui->gas->isEnabled())
m_backupGas = ui->gas->value();
ui->gas->setValue((qint64)Interface::txGas(m_data));
ui->gas->setMinimum(base);
ui->gas->setValue(base);
ui->gas->setEnabled(false);
}
ui->code->setHtml("<h3>NatSpec</h3>" + natspec + "<h3>Dump</h3>" + QString::fromStdString(dev::memDump(m_data, 8, true)) + "<h3>Hex</h3>" + Div(Mono) + QString::fromStdString(toHex(m_data)) + "</div>");
ui->code->setHtml(errs + "<h3>NatSpec</h3>" + natspec + "<h3>Dump</h3>" + QString::fromStdString(dev::memDump(m_data, 8, true)) + "<h3>Hex</h3>" + Div(Mono) + QString::fromStdString(toHex(m_data)) + "</div>");
}
updateFee();
}

Loading…
Cancel
Save