Browse Source

Avoid recursion in TransactionQueue.

cl-refactor
Gav Wood 11 years ago
parent
commit
34ab7e8231
  1. 14
      libethereum/BlockQueue.cpp
  2. 11
      libethereum/Transaction.cpp
  3. 7
      libethereum/Transaction.h
  4. 12
      libethereum/TransactionQueue.cpp

14
libethereum/BlockQueue.cpp

@ -85,18 +85,20 @@ bool BlockQueue::import(bytesConstRef _block, BlockChain const& _bc)
return true; return true;
} }
void BlockQueue::noteReadyWithoutWriteGuard(h256 _b) void BlockQueue::noteReadyWithoutWriteGuard(h256 _good)
{ {
auto r = m_future.equal_range(_b); h256s goodQueue(1, _good);
h256s good; while (goodQueue.size())
{
auto r = m_future.equal_range(goodQueue.back());
goodQueue.pop_back();
for (auto it = r.first; it != r.second; ++it) for (auto it = r.first; it != r.second; ++it)
{ {
m_futureSet.erase(it->second.first); m_futureSet.erase(it->second.first);
m_ready.push_back(it->second.second); m_ready.push_back(it->second.second);
m_readySet.erase(it->second.first); m_readySet.erase(it->second.first);
good.push_back(it->second.first); goodQueue.push_back(it->second.first);
} }
m_future.erase(r.first, r.second); m_future.erase(r.first, r.second);
for (auto g: good) }
noteReadyWithoutWriteGuard(g);
} }

11
libethereum/Transaction.cpp

@ -29,7 +29,7 @@ using namespace eth;
#define ETH_ADDRESS_DEBUG 0 #define ETH_ADDRESS_DEBUG 0
Transaction::Transaction(bytesConstRef _rlpData) Transaction::Transaction(bytesConstRef _rlpData, bool _checkSender)
{ {
int field = 0; int field = 0;
RLP rlp(_rlpData); RLP rlp(_rlpData);
@ -42,6 +42,8 @@ Transaction::Transaction(bytesConstRef _rlpData)
value = rlp[field = 4].toInt<u256>(); value = rlp[field = 4].toInt<u256>();
data = rlp[field = 5].toBytes(); data = rlp[field = 5].toBytes();
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>() };
if (_checkSender)
m_sender = sender();
} }
catch (RLPException const&) catch (RLPException const&)
{ {
@ -63,6 +65,8 @@ Address Transaction::safeSender() const noexcept
Address Transaction::sender() const Address Transaction::sender() const
{ {
if (!m_sender)
{
secp256k1_start(); secp256k1_start();
h256 sig[2] = { vrs.r, vrs.s }; h256 sig[2] = { vrs.r, vrs.s };
@ -74,7 +78,7 @@ Address Transaction::sender() const
throw InvalidSignature(); throw InvalidSignature();
// TODO: check right160 is correct and shouldn't be left160. // TODO: check right160 is correct and shouldn't be left160.
auto ret = right160(eth::sha3(bytesConstRef(&(pubkey[1]), 64))); m_sender = right160(eth::sha3(bytesConstRef(&(pubkey[1]), 64)));
#if ETH_ADDRESS_DEBUG #if ETH_ADDRESS_DEBUG
cout << "---- RECOVER -------------------------------" << endl; cout << "---- RECOVER -------------------------------" << endl;
@ -83,7 +87,8 @@ Address Transaction::sender() const
cout << "PUB: " << toHex(bytesConstRef(&(pubkey[1]), 64)) << endl; cout << "PUB: " << toHex(bytesConstRef(&(pubkey[1]), 64)) << endl;
cout << "ADR: " << ret << endl; cout << "ADR: " << ret << endl;
#endif #endif
return ret; }
return m_sender;
} }
void Transaction::sign(Secret _priv) void Transaction::sign(Secret _priv)

7
libethereum/Transaction.h

@ -38,8 +38,8 @@ struct Signature
struct Transaction struct Transaction
{ {
Transaction() {} Transaction() {}
Transaction(bytesConstRef _rlp); Transaction(bytesConstRef _rlp, bool _checkSender = false);
Transaction(bytes const& _rlp): Transaction(&_rlp) {} Transaction(bytes const& _rlp, bool _checkSender = false): Transaction(&_rlp, _checkSender) {}
bool operator==(Transaction const& _c) const { return receiveAddress == _c.receiveAddress && value == _c.value && data == _c.data; } bool operator==(Transaction const& _c) const { return receiveAddress == _c.receiveAddress && value == _c.value && data == _c.data; }
bool operator!=(Transaction const& _c) const { return !operator==(_c); } bool operator!=(Transaction const& _c) const { return !operator==(_c); }
@ -67,6 +67,9 @@ struct Transaction
std::string rlpString(bool _sig = true) const { return asString(rlp(_sig)); } std::string rlpString(bool _sig = true) const { return asString(rlp(_sig)); }
h256 sha3(bool _sig = true) const { RLPStream s; fillStream(s, _sig); return eth::sha3(s.out()); } h256 sha3(bool _sig = true) const { RLPStream s; fillStream(s, _sig); return eth::sha3(s.out()); }
bytes sha3Bytes(bool _sig = true) const { RLPStream s; fillStream(s, _sig); return eth::sha3Bytes(s.out()); } bytes sha3Bytes(bool _sig = true) const { RLPStream s; fillStream(s, _sig); return eth::sha3Bytes(s.out()); }
private:
mutable Address m_sender;
}; };
using Transactions = std::vector<Transaction>; using Transactions = std::vector<Transaction>;

12
libethereum/TransactionQueue.cpp

@ -27,22 +27,22 @@
using namespace std; using namespace std;
using namespace eth; using namespace eth;
bool TransactionQueue::import(bytesConstRef _block) bool TransactionQueue::import(bytesConstRef _transactionRLP)
{ {
// Check if we already know this transaction. // Check if we already know this transaction.
h256 h = sha3(_block); h256 h = sha3(_transactionRLP);
if (m_known.count(h)) if (m_known.count(h))
return false; return false;
try try
{ {
// Check validity of _block as a transaction. To do this we just deserialise and attempt to determine the sender. If it doesn't work, the signature is bad. // Check validity of _transactionRLP as a transaction. To do this we just deserialise and attempt to determine the sender.
// If it doesn't work, the signature is bad.
// The transaction's nonce may yet be invalid (or, it could be "valid" but we may be missing a marginally older transaction). // The transaction's nonce may yet be invalid (or, it could be "valid" but we may be missing a marginally older transaction).
Transaction t(_block); Transaction t(_transactionRLP, true);
auto s = t.sender();
// If valid, append to blocks. // If valid, append to blocks.
m_current[h] = _block.toBytes(); m_current[h] = _transactionRLP.toBytes();
} }
catch (InvalidTransactionFormat const& _e) catch (InvalidTransactionFormat const& _e)
{ {

Loading…
Cancel
Save