Browse Source

Transaction injection.

cl-refactor
Gav Wood 11 years ago
parent
commit
0f3c3ff609
  1. 6
      alethzero/Main.ui
  2. 21
      alethzero/MainWin.cpp
  3. 1
      alethzero/MainWin.h
  4. 5
      libethcore/TrieDB.h
  5. 7
      libethereum/Client.cpp
  6. 2
      libethereum/Client.h
  7. 5
      libethereum/Executive.cpp
  8. 2
      libethereum/PeerServer.cpp
  9. 11
      libethereum/State.cpp
  10. 4
      libethereum/TransactionQueue.cpp
  11. 5
      libethereum/TransactionQueue.h

6
alethzero/Main.ui

@ -154,6 +154,7 @@
<addaction name="debugStep"/>
<addaction name="paranoia"/>
<addaction name="killBlockchain"/>
<addaction name="inject"/>
</widget>
<addaction name="menu_File"/>
<addaction name="menu_Network"/>
@ -1045,6 +1046,11 @@
<string>&amp;Export Selected Key...</string>
</property>
</action>
<action name="inject">
<property name="text">
<string>&amp;Inject Transaction</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>

21
alethzero/MainWin.cpp

@ -673,6 +673,14 @@ void Main::ourAccountsRowsMoved()
m_myKeys = myKeys;
}
void Main::on_inject_triggered()
{
QString s = QInputDialog::getText(this, "Inject Transaction", "Enter transaction dump in hex");
bytes b = fromHex(s.toStdString());
m_client->inject(&b);
refresh();
}
void Main::on_blocks_currentItemChanged()
{
ui->info->clear();
@ -727,6 +735,10 @@ void Main::on_blocks_currentItemChanged()
s << "&nbsp;&emsp;&nbsp;#<b>" << tx.nonce << "</b>";
s << "<br/>Gas price: <b>" << formatBalance(tx.gasPrice) << "</b>";
s << "<br/>Gas: <b>" << tx.gas << "</b>";
s << "<br/>V: <b>" << hex << (int)tx.vrs.v << "</b>";
s << "<br/>R: <b>" << hex << tx.vrs.r << "</b>";
s << "<br/>S: <b>" << hex << tx.vrs.s << "</b>";
s << "<br/>Msg: <b>" << tx.sha3(false) << "</b>";
if (tx.isCreation())
{
if (tx.data.size())
@ -747,7 +759,7 @@ void Main::on_blocks_currentItemChanged()
void Main::on_contracts_currentItemChanged()
{
ui->contractInfo->clear();
m_client->lock();
eth::ClientGuard l(&*m_client);
if (auto item = ui->contracts->currentItem())
{
auto hba = item->data(Qt::UserRole).toByteArray();
@ -761,7 +773,6 @@ void Main::on_contracts_currentItemChanged()
s << "<h4>Body Code</h4>" << disassemble(state().code(h));
ui->contractInfo->appendHtml(QString::fromStdString(s.str()));
}
m_client->unlock();
}
void Main::on_idealPeers_valueChanged()
@ -1033,7 +1044,7 @@ void Main::on_send_clicked()
{
debugFinished();
u256 totalReq = value() + fee();
m_client->lock();
eth::ClientGuard l(&*m_client);
for (auto i: m_myKeys)
if (m_client->state().balance(i.address()) >= totalReq)
{
@ -1046,7 +1057,6 @@ void Main::on_send_clicked()
refresh();
return;
}
m_client->unlock();
statusBar()->showMessage("Couldn't make transaction: no single account contains at least the required amount.");
}
@ -1054,7 +1064,7 @@ void Main::on_debug_clicked()
{
debugFinished();
u256 totalReq = value() + fee();
m_client->lock();
eth::ClientGuard l(&*m_client);
for (auto i: m_myKeys)
if (m_client->state().balance(i.address()) >= totalReq)
{
@ -1088,7 +1098,6 @@ void Main::on_debug_clicked()
updateDebugger();
return;
}
m_client->unlock();
statusBar()->showMessage("Couldn't make transaction: no single account contains at least the required amount.");
}

1
alethzero/MainWin.h

@ -79,6 +79,7 @@ private slots:
void on_killBlockchain_triggered();
void on_importKey_triggered();
void on_exportKey_triggered();
void on_inject_triggered();
void refresh(bool _override = false);
void refreshNetwork();

5
libethcore/TrieDB.h

@ -61,6 +61,8 @@ inline std::ostream& operator<<(std::ostream& _out, BasicMap const& _m)
return _out;
}
class InvalidTrie: public std::exception {};
class Overlay: public BasicMap
{
public:
@ -196,8 +198,7 @@ public:
cdebug << rlp;
auto c = rlp.itemCount();
cdebug << c;
m_that = nullptr;
return;
throw InvalidTrie();
assert(rlp.isList() && (rlp.itemCount() == 2 || rlp.itemCount() == 17));
}
if (rlp.itemCount() == 2)

7
libethereum/Client.cpp

@ -174,6 +174,13 @@ Address Client::transact(Secret _secret, u256 _endowment, bytes const& _init, u2
return right160(sha3(rlpList(t.sender(), t.nonce)));
}
void Client::inject(bytesConstRef _rlp)
{
lock_guard<recursive_mutex> l(m_lock);
m_tq.attemptImport(_rlp);
m_changed = true;
}
void Client::work()
{
bool changed = false;

2
libethereum/Client.h

@ -90,6 +90,8 @@ public:
/// @returns the new contract's address (assuming it all goes through).
Address transact(Secret _secret, u256 _endowment, bytes const& _init, u256 _gas = 10000, u256 _gasPrice = 10 * szabo);
void inject(bytesConstRef _rlp);
/// Makes the given call. Nothing is recorded into the state. TODO
// bytes call(Secret _secret, u256 _amount, u256 _gasPrice, Address _dest, u256 _gas, bytes _data = bytes());

5
libethereum/Executive.cpp

@ -108,6 +108,11 @@ void Executive::call(Address _receiveAddress, Address _senderAddress, u256 _valu
void Executive::create(Address _sender, u256 _endowment, u256 _gasPrice, u256 _gas, bytesConstRef _init, Address _origin)
{
#if ETH_PARANOIA
#endif
m_newAddress = right160(sha3(rlpList(_sender, m_s.transactionsFrom(_sender) - 1)));
while (m_s.addressInUse(m_newAddress))
m_newAddress = (u160)m_newAddress + 1;

2
libethereum/PeerServer.cpp

@ -363,7 +363,7 @@ bool PeerServer::sync(BlockChain& _bc, TransactionQueue& _tq, Overlay& _o)
if (m_mode == NodeMode::Full)
{
for (auto it = m_incomingTransactions.begin(); it != m_incomingTransactions.end(); ++it)
if (_tq.import(*it))
if (_tq.import(&*it))
{}//ret = true; // just putting a transaction in the queue isn't enough to change the state - it might have an invalid nonce...
else
m_transactionsSent.insert(sha3(*it)); // if we already had the transaction, then don't bother sending it on.

11
libethereum/State.cpp

@ -158,15 +158,10 @@ struct CachedAddressState
std::map<u256, u256> ret;
if (r)
{
cdebug << "MemDB: " << r[2].toHash<h256>();
TrieDB<h256, Overlay> memdb(const_cast<Overlay*>(o), r[2].toHash<h256>()); // promise we won't alter the overlay! :)
cdebug << memdb.root();
for (auto const& j: memdb)
{
cdebug << j.first;
ret[j.first] = RLP(j.second).toInt<u256>();
}
}
if (s)
for (auto const& j: s->storage())
if ((!ret.count(j.first) && j.second) || (ret.count(j.first) && ret.at(j.first) != j.second))
@ -859,6 +854,8 @@ u256 State::execute(bytesConstRef _rlp)
commit(); // get an updated hash
#endif
// TODO: CHECK TRIE
State old(*this);
auto h = rootHash();
@ -866,6 +863,7 @@ u256 State::execute(bytesConstRef _rlp)
e.setup(_rlp);
cnote << "Executing" << e.t() << "on" << h;
cnote << toHex(e.t().rlp(true));
u256 startGasUsed = gasUsed();
if (startGasUsed + e.t().gas > m_currentBlock.gasLimit)
@ -882,6 +880,9 @@ u256 State::execute(bytesConstRef _rlp)
cnote << "Executed; now" << rootHash();
cnote << old.diff(*this);
// TODO: CHECK TRIE
// TODO: CHECK TRIE after level DB flush to make sure exactly the same.
// Add to the user-originated transactions that we've executed.
m_transactions.push_back(TransactionReceipt(e.t(), rootHash(), startGasUsed + e.gasUsed()));
m_transactionSet.insert(e.t().sha3());

4
libethereum/TransactionQueue.cpp

@ -27,7 +27,7 @@
using namespace std;
using namespace eth;
bool TransactionQueue::import(bytes const& _block)
bool TransactionQueue::import(bytesConstRef _block)
{
// Check if we already know this transaction.
h256 h = sha3(_block);
@ -44,7 +44,7 @@ bool TransactionQueue::import(bytes const& _block)
m_interestQueue.push_back(t);
// If valid, append to blocks.
m_data[h] = _block;
m_data[h] = _block.toBytes();
}
catch (InvalidTransactionFormat const& _e)
{

5
libethereum/TransactionQueue.h

@ -35,8 +35,9 @@ class BlockChain;
class TransactionQueue
{
public:
bool attemptImport(bytes const& _block) { try { import(_block); return true; } catch (...) { return false; } }
bool import(bytes const& _block);
bool attemptImport(bytesConstRef _block) { try { import(_block); return true; } catch (...) { return false; } }
bool attemptImport(bytes const& _block) { try { import(&_block); return true; } catch (...) { return false; } }
bool import(bytesConstRef _block);
void drop(h256 _txHash) { m_data.erase(_txHash); }
std::map<h256, bytes> const& transactions() const { return m_data; }

Loading…
Cancel
Save