From 3525a62ccb7c4d1d80d31bc5b80b14e69f999f87 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 7 Apr 2015 01:57:10 +0200 Subject: [PATCH] Diagnostics for checking transaction dropping/resubmission --- libethereum/Client.cpp | 25 +++++++++++++++++++++++-- libethereum/Client.h | 5 +++++ libethereum/EthereumHost.cpp | 16 +++++++++++++--- libethereum/EthereumHost.h | 6 ++++++ 4 files changed, 47 insertions(+), 5 deletions(-) diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index c8d0482c2..4ad20b403 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -505,13 +505,27 @@ void Client::doWork() bool sgw; tie(fresh, dead, sgw) = m_bc.sync(m_bq, db, 100); - // TODO: remove transactions from m_tq nicely rather than relying on out of date nonce later on. + // insert transactions that we are declaring the dead part of the chain for (auto const& h: dead) + { + clog(ClientNote) << "Dead block:" << h.abridged(); for (auto const& t: m_bc.transactions(h)) + { + clog(ClientNote) << "Resubmitting transaction " << Transaction(t, CheckSignature::None); m_tq.import(t); + } + } + + // remove transactions from m_tq nicely rather than relying on out of date nonce later on. for (auto const& h: fresh) + { + clog(ClientChat) << "Mined block:" << h.abridged(); for (auto const& th: m_bc.transactionHashes(h)) + { + clog(ClientNote) << "Safely dropping transaction " << th; m_tq.drop(th); + } + } stillGotWork = stillGotWork | sgw; if (!fresh.empty()) @@ -535,7 +549,7 @@ void Client::doWork() // TODO: Move transactions pending from m_postMine back to transaction queue. } - // returns h256s as blooms, once for each transaction. + // returns TransactionReceipts, once for each transaction. cwork << "postSTATE <== TQ"; TransactionReceipts newPendingReceipts = m_postMine.sync(m_bc, m_tq, *m_gp); if (newPendingReceipts.size()) @@ -548,8 +562,15 @@ void Client::doWork() if (isMining()) cnote << "Additional transaction ready: Restarting mining operation."; resyncStateNeeded = true; + if (auto h = m_host.lock()) + h->noteNewTransactions(); } } + + if (!changeds.empty()) + if (auto h = m_host.lock()) + h->noteNewBlocks(); + if (resyncStateNeeded) { ReadGuard l(x_localMiners); diff --git a/libethereum/Client.h b/libethereum/Client.h index 1891f34ca..bdd875e95 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -114,6 +114,11 @@ private: std::array m_octiles; }; +struct ClientNote: public LogChannel { static const char* name() { return "*C*"; } static const int verbosity = 2; }; +struct ClientChat: public LogChannel { static const char* name() { return "=C="; } static const int verbosity = 4; }; +struct ClientTrace: public LogChannel { static const char* name() { return "-C-"; } static const int verbosity = 7; }; +struct ClientDetail: public LogChannel { static const char* name() { return " C "; } static const int verbosity = 14; }; + /** * @brief Main API hub for interfacing with Ethereum. */ diff --git a/libethereum/EthereumHost.cpp b/libethereum/EthereumHost.cpp index cb29980fd..6a69a6d55 100644 --- a/libethereum/EthereumHost.cpp +++ b/libethereum/EthereumHost.cpp @@ -159,8 +159,16 @@ void EthereumHost::doWork() // If we've finished our initial sync (including getting all the blocks into the chain so as to reduce invalid transactions), start trading transactions & blocks if (!isSyncing() && m_chain.isKnown(m_latestBlockSent)) { - maintainTransactions(); - maintainBlocks(h); + if (m_newTransactions) + { + m_newTransactions = false; + maintainTransactions(); + } + if (m_newBlocks) + { + m_newBlocks = false; + maintainBlocks(h); + } } for (auto p: peerSessions()) @@ -192,8 +200,10 @@ void EthereumHost::maintainTransactions() { b += ts[h].rlp(); ++n; - m_transactionsSent.insert(h); } + for (auto const& t: ts) + m_transactionsSent.insert(t.first); + ep->clearKnownTransactions(); if (n || ep->m_requireTransactions) diff --git a/libethereum/EthereumHost.h b/libethereum/EthereumHost.h index fad0b8edd..c2fffcd82 100644 --- a/libethereum/EthereumHost.h +++ b/libethereum/EthereumHost.h @@ -76,6 +76,9 @@ public: bool isBanned(p2p::NodeId _id) const { return !!m_banned.count(_id); } + void noteNewTransactions() { m_newTransactions = true; } + void noteNewBlocks() { m_newBlocks = true; } + private: std::vector> randomSelection(unsigned _percent = 25, std::function const& _allow = [](EthereumPeer const*){ return true; }); @@ -121,6 +124,9 @@ private: h256Set m_transactionsSent; std::set m_banned; + + bool m_newTransactions = false; + bool m_newBlocks = false; }; }