Browse Source

External Debugger for debugging past transactions, too.

cl-refactor
Gav Wood 10 years ago
parent
commit
513fc897d8
  1. 16
      alethzero/Debugger.cpp
  2. 4
      alethzero/Debugger.h
  3. 22
      alethzero/MainWin.cpp
  4. 4
      libethereum/BlockChain.h
  5. 6
      libethereum/Executive.cpp
  6. 5
      libethereum/Executive.h

16
alethzero/Debugger.cpp

@ -56,18 +56,26 @@ void Debugger::init()
}
}
void Debugger::populate(dev::eth::Executive& _executive, dev::bytesConstRef _transactionRLP)
void Debugger::populate(dev::eth::Executive& _executive, dev::eth::Transaction const& _transaction)
{
finished();
if (m_session.populate(_executive, _transactionRLP))
if (m_session.populate(_executive, _transaction))
init();
update();
}
bool DebugSession::populate(dev::eth::Executive& _executive, dev::bytesConstRef _transactionRLP)
bool DebugSession::populate(dev::eth::Executive& _executive, dev::eth::Transaction const& _transaction)
{
if (_executive.setup(_transactionRLP))
try {
if (_executive.setup(_transaction))
return false;
}
catch (...)
{
// Invalid transaction
return false;
}
vector<WorldState const*> levels;
bytes lastExtCode;
bytesConstRef lastData;

4
alethzero/Debugger.h

@ -53,7 +53,7 @@ struct DebugSession
{
DebugSession() {}
bool populate(dev::eth::Executive& _executive, dev::bytesConstRef _transactionRLP);
bool populate(dev::eth::Executive& _executive, dev::eth::Transaction const& _transaction);
dev::h256 currentCode;
dev::h256 currentData;
@ -73,7 +73,7 @@ public:
explicit Debugger(Context* _context, QWidget* _parent = 0);
~Debugger();
void populate(dev::eth::Executive& _executive, dev::bytesConstRef _transactionRLP);
void populate(dev::eth::Executive& _executive, dev::eth::Transaction const& _transaction);
protected slots:
void on_callStack_currentItemChanged();

22
alethzero/MainWin.cpp

@ -1478,13 +1478,12 @@ void Main::on_debugCurrent_triggered()
if (!item->data(Qt::UserRole + 1).isNull())
{
unsigned txi = item->data(Qt::UserRole + 1).toInt();
m_executiveState = ethereum()->state(txi + 1, h);
m_currentExecution = unique_ptr<Executive>(new Executive(m_executiveState, ethereum()->blockChain(), 0));
Transaction t = m_executiveState.pending()[txi];
m_executiveState = m_executiveState.fromPending(txi);
auto r = t.rlp();
populateDebugger(&r);
m_currentExecution.reset();
bytes t = ethereum()->blockChain().transaction(h, txi);
State s(ethereum()->state(txi, h));
Executive e(s, ethereum()->blockChain(), 0);
Debugger dw(this, this);
dw.populate(e, Transaction(t, CheckSignature::Sender));
dw.exec();
}
}
}
@ -1991,7 +1990,6 @@ void Main::keysChanged()
void Main::on_debug_clicked()
{
debugFinished();
try
{
u256 totalReq = value() + fee();
@ -2002,16 +2000,10 @@ void Main::on_debug_clicked()
Transaction t = isCreation() ?
Transaction(value(), gasPrice(), ui->gas->value(), m_data, m_executiveState.transactionsFrom(dev::toAddress(s)), s) :
Transaction(value(), gasPrice(), ui->gas->value(), fromString(ui->destination->currentText()), m_data, m_executiveState.transactionsFrom(dev::toAddress(s)), s);
auto r = t.rlp();
Debugger dw(this, this);
Executive e(m_executiveState, ethereum()->blockChain(), 0);
dw.populate(e, &r);
dw.populate(e, t);
dw.exec();
/*m_executiveState = ethereum()->postState();
m_currentExecution = unique_ptr<Executive>(new Executive(m_executiveState, ethereum()->blockChain(), 0));
populateDebugger(&r);
m_currentExecution.reset();*/
return;
}
statusBar()->showMessage("Couldn't make transaction: no single account contains at least the required amount.");

4
libethereum/BlockChain.h

@ -112,6 +112,10 @@ public:
bytes block(h256 _hash) const;
bytes block() const { return block(currentHash()); }
/// Get a block's transaction (RLP format) for the given block hash (or the most recent mined if none given) & index. Thread-safe.
bytes transaction(h256 _hash, unsigned _i) const { bytes b = block(_hash); return RLP(b)[1][_i].data().toBytes(); }
bytes transaction(unsigned _i) const { return transaction(currentHash(), _i); }
/// Get a number for the given hash (or the most recent mined if none given). Thread-safe.
unsigned number(h256 _hash) const { return details(_hash).number; }
unsigned number() const { return number(currentHash()); }

6
libethereum/Executive.cpp

@ -54,6 +54,12 @@ bool Executive::setup(bytesConstRef _rlp)
{
// Entry point for a user-executed transaction.
m_t = Transaction(_rlp, CheckSignature::Sender);
return setup();
}
bool Executive::setup()
{
// Entry point for a user-executed transaction.
// Avoid invalid transactions.
auto nonceReq = m_s.transactionsFrom(m_t.sender());

5
libethereum/Executive.h

@ -62,6 +62,9 @@ public:
/// Set up the executive for evaluating a transaction. You must call finalize() following this.
/// @returns true iff go() must be called (and thus a VM execution in required).
bool setup(bytesConstRef _transaction);
/// Set up the executive for evaluating a transaction. You must call finalize() following this.
/// @returns true iff go() must be called (and thus a VM execution in required).
bool setup(Transaction const& _transaction) { m_t = _transaction; return setup(); }
/// Finalise a transaction previously set up with setup().
/// @warning Only valid after setup(), and possibly go().
void finalize();
@ -101,6 +104,8 @@ public:
bool excepted() const { return m_excepted; }
private:
bool setup();
State& m_s; ///< The state to which this operation/transaction is applied.
LastHashes m_lastHashes;
std::shared_ptr<ExtVM> m_ext; ///< The VM externality object for the VM execution or null if no VM is required.

Loading…
Cancel
Save