Browse Source

Better handling of bad transactions.

cl-refactor
Gav Wood 11 years ago
parent
commit
da4144bbb6
  1. 99
      TODO
  2. 2
      libethereum/Exceptions.h
  3. 5
      libethereum/PeerNetwork.cpp
  4. 22
      libethereum/Transaction.cpp
  5. 7
      libethereum/TransactionQueue.cpp

99
TODO

@ -1,99 +0,0 @@
### UP FOR GRABS
For PoC-4:
GUI
- Make address/block chain list model-based, JIT populated.
- Make everything else model-based
- Qt/QML class.
Core
- Signalling for changes to State.
THREAD-SAFETY
- BlockChain
- TransactionQueue
- State
Robustness
- Store version alongside BC DB. Kill old DBs when protocol different. Remove block chain on protocol change (i.e. store protocol with block chain).
Cleanups & caching
- All caches should flush unused data (I'm looking at you, BlockChain) to avoid memory overload.
Generally:
Crypto stuff:
- kFromMessage
- Check all the tweak instructions.
Network:
- *** Exponential backoff on bad connection.
- *** Handle exception when no network.
- NotInChain will be very bad for new peers - it'll run through until the genesis.
- Check how many it has first.
- Crypto on network - use id as public key?
- Make work with IPv6
- Peers rated.
- Useful/useless - new blocks/transactions or useful peers?
- Solid communications?
- Strategy for peer suggestion?
- Ignore transactions with future nonces until address's nonce changes.
Cleanups & caching
- State DB should keep only last few N blocks worth of nodes (except for restore points - configurable, defaults to every 30000th block - all blocks that are restore points should be stored so their stateRoots are known good).
General:
- Better logging.
- Colours.
- Move over to new system.
Robustness
- Remove aborts
- Recover from all exceptions.
- Especially RLP & other I/O.
- RLP should never assert; only throw.
- Better handling of corrupt blocks.
- Kill DB & restart.
GUI:
- Turn on/off debug channels.
### Marko
Ubuntu builds
- Raring (branch, local, x64 only :-( )
- Quantal (branch) (Launchpad)
- Saucy (master) (Launchpad)
### Alex
Mac build.
Mac build instructions.
### Eric
Windows XC build.
Windows XC build instructions.
### Tim/Harv
Windows MSVC build.
Windows MSVC build instructions.
LATER:
Trie on DB.
- Move the restore point stuff into block restore points
- i.e. keep all nodes from last 127 blocks with counter, at 128, kill but keep every (60*24*7)th or so i.e. one per week as a restore point.
- maybe allow this to be configured.
### TIM
Stateful Miner class.
Better Mod-Exp.

2
libethereum/Exceptions.h

@ -31,7 +31,7 @@ class NoSuchContract: public Exception {};
class ContractAddressCollision: public Exception {}; class ContractAddressCollision: public Exception {};
class FeeTooSmall: public Exception {}; class FeeTooSmall: public Exception {};
class InvalidSignature: public Exception {}; class InvalidSignature: public Exception {};
class InvalidTransactionFormat: public Exception {}; class InvalidTransactionFormat: public Exception { public: InvalidTransactionFormat(int _f, bytesConstRef _d): m_f(_f), m_d(_d.toBytes()) {} int m_f; bytes m_d; virtual std::string description() const { return "Invalid transaction format: Bad field " + toString(m_f) + " (" + asHex(m_d) + ")"; } };
class InvalidBlockFormat: public Exception { public: InvalidBlockFormat(int _f, bytesConstRef _d): m_f(_f), m_d(_d.toBytes()) {} int m_f; bytes m_d; virtual std::string description() const { return "Invalid block format: Bad field " + toString(m_f) + " (" + asHex(m_d) + ")"; } }; class InvalidBlockFormat: public Exception { public: InvalidBlockFormat(int _f, bytesConstRef _d): m_f(_f), m_d(_d.toBytes()) {} int m_f; bytes m_d; virtual std::string description() const { return "Invalid block format: Bad field " + toString(m_f) + " (" + asHex(m_d) + ")"; } };
class InvalidBlockHeaderFormat: public Exception { public: InvalidBlockHeaderFormat(int _f, bytesConstRef _d): m_f(_f), m_d(_d.toBytes()) {} int m_f; bytes m_d; virtual std::string description() const { return "Invalid block header format: Bad field " + toString(m_f) + " (" + asHex(m_d) + ")"; } }; class InvalidBlockHeaderFormat: public Exception { public: InvalidBlockHeaderFormat(int _f, bytesConstRef _d): m_f(_f), m_d(_d.toBytes()) {} int m_f; bytes m_d; virtual std::string description() const { return "Invalid block header format: Bad field " + toString(m_f) + " (" + asHex(m_d) + ")"; } };
class InvalidUnclesHash: public Exception {}; class InvalidUnclesHash: public Exception {};

5
libethereum/PeerNetwork.cpp

@ -591,6 +591,8 @@ void PeerSession::doRead()
{ {
if (m_incoming[0] != 0x22 || m_incoming[1] != 0x40 || m_incoming[2] != 0x08 || m_incoming[3] != 0x91) if (m_incoming[0] != 0x22 || m_incoming[1] != 0x40 || m_incoming[2] != 0x08 || m_incoming[3] != 0x91)
{ {
disconnect(BadProtocol);
return;
clogS(NetWarn) << "Out of alignment. Skipping: " << hex << showbase << (int)m_incoming[0] << dec; clogS(NetWarn) << "Out of alignment. Skipping: " << hex << showbase << (int)m_incoming[0] << dec;
memmove(m_incoming.data(), m_incoming.data() + 1, m_incoming.size() - 1); memmove(m_incoming.data(), m_incoming.data() + 1, m_incoming.size() - 1);
m_incoming.resize(m_incoming.size() - 1); m_incoming.resize(m_incoming.size() - 1);
@ -610,6 +612,7 @@ void PeerSession::doRead()
cerr << "Received " << len << ": " << asHex(bytesConstRef(m_incoming.data() + 8, len)) << endl; cerr << "Received " << len << ": " << asHex(bytesConstRef(m_incoming.data() + 8, len)) << endl;
cwarn << "INVALID MESSAGE RECEIVED"; cwarn << "INVALID MESSAGE RECEIVED";
disconnect(BadProtocol); disconnect(BadProtocol);
return;
} }
else else
{ {
@ -831,7 +834,7 @@ void PeerServer::ensureAccepting()
clog(NetWarn) << "ERROR: " << _e.what(); clog(NetWarn) << "ERROR: " << _e.what();
} }
m_accepting = false; m_accepting = false;
if (ec.value() != 1 && m_mode == NodeMode::PeerServer || m_peers.size() < m_idealPeerCount * 2) if (ec.value() != 1 && (m_mode == NodeMode::PeerServer || m_peers.size() < m_idealPeerCount * 2))
ensureAccepting(); ensureAccepting();
}); });
} }

22
libethereum/Transaction.cpp

@ -30,14 +30,22 @@ using namespace eth;
Transaction::Transaction(bytesConstRef _rlpData) Transaction::Transaction(bytesConstRef _rlpData)
{ {
int field = 0;
RLP rlp(_rlpData); RLP rlp(_rlpData);
nonce = rlp[0].toInt<u256>(); try
receiveAddress = rlp[1].toHash<Address>(); {
value = rlp[2].toInt<u256>(); nonce = rlp[field = 0].toInt<u256>();
data.reserve(rlp[3].itemCountStrict()); receiveAddress = rlp[field = 1].toHash<Address>();
for (auto const& i: rlp[3]) value = rlp[field = 2].toInt<u256>();
data.push_back(i.toInt<u256>()); data.reserve(rlp[field = 3].itemCountStrict());
vrs = Signature{ rlp[4].toInt<byte>(), rlp[5].toInt<u256>(), rlp[6].toInt<u256>() }; for (auto const& i: rlp[3])
data.push_back(i.toInt<u256>());
vrs = Signature{ rlp[field = 4].toInt<byte>(), rlp[field = 5].toInt<u256>(), rlp[field = 6].toInt<u256>() };
}
catch (RLPException const&)
{
throw InvalidTransactionFormat(field, rlp[field].data());
}
} }
Address Transaction::safeSender() const noexcept Address Transaction::safeSender() const noexcept

7
libethereum/TransactionQueue.cpp

@ -43,9 +43,14 @@ bool TransactionQueue::import(bytes const& _block)
// If valid, append to blocks. // If valid, append to blocks.
m_data[h] = _block; m_data[h] = _block;
} }
catch (InvalidTransactionFormat const& _e)
{
cwarn << "Ignoring invalid transaction: " << _e.description();
return false;
}
catch (std::exception const& _e) catch (std::exception const& _e)
{ {
cout << "*** Ignoring invalid transaction: " << _e.what(); cwarn << "Ignoring invalid transaction: " << _e.what();
return false; return false;
} }

Loading…
Cancel
Save