From 8c6b653790634c2451068682a4534f836264937e Mon Sep 17 00:00:00 2001 From: arkpar Date: Tue, 28 Jul 2015 16:02:44 +0200 Subject: [PATCH] clear state on dropping transactions from queue --- libethereum/Client.cpp | 16 ++++++++++++++++ libethereum/Client.h | 4 ++++ libethereum/TransactionQueue.cpp | 6 +++++- libethereum/TransactionQueue.h | 4 ++++ 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 0ffc4dcd7..7a9172a90 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -94,6 +94,7 @@ void Client::init(p2p::Host* _extNet, std::string const& _dbPath, WithExisting _ m_lastGetWork = std::chrono::system_clock::now() - chrono::seconds(30); m_tqReady = m_tq.onReady([=](){ this->onTransactionQueueReady(); }); // TODO: should read m_tq->onReady(thisThread, syncTransactionQueue); + m_tqReplaced = m_tq.onReplaced([=](h256 const&){ this->resetState(); }); m_bqReady = m_bq.onReady([=](){ this->onBlockQueueReady(); }); // TODO: should read m_bq->onReady(thisThread, syncBlockQueue); m_bq.setOnBad([=](Exception& ex){ this->onBadBlock(ex); }); bc().setOnBad([=](Exception& ex){ this->onBadBlock(ex); }); @@ -650,6 +651,21 @@ void Client::resyncStateFromChain() } } +void Client::resetState() +{ + State newPreMine; + DEV_READ_GUARDED(x_preMine) + newPreMine = m_preMine; + + DEV_WRITE_GUARDED(x_working) + m_working = newPreMine; + DEV_READ_GUARDED(x_working) DEV_WRITE_GUARDED(x_postMine) + m_postMine = m_working; + + onPostStateChanged(); + onTransactionQueueReady(); +} + void Client::onChainChanged(ImportRoute const& _ir) { h256Hash changeds; diff --git a/libethereum/Client.h b/libethereum/Client.h index 630898b20..973270877 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -254,6 +254,9 @@ protected: /// Called after processing blocks by onChainChanged(_ir) void resyncStateFromChain(); + /// Clear working state of transactions + void resetState(); + /// Magically called when the chain has changed. An import route is provided. /// Called by either submitWork() or in our main thread through syncBlockQueue(). void onChainChanged(ImportRoute const& _ir); @@ -307,6 +310,7 @@ protected: std::shared_ptr m_sealEngine; ///< Our block-sealing engine. Handler<> m_tqReady; + Handler m_tqReplaced; Handler<> m_bqReady; bool m_wouldMine = false; ///< True if we /should/ be mining. diff --git a/libethereum/TransactionQueue.cpp b/libethereum/TransactionQueue.cpp index 5de86c818..aeeb35214 100644 --- a/libethereum/TransactionQueue.cpp +++ b/libethereum/TransactionQueue.cpp @@ -147,7 +147,11 @@ ImportResult TransactionQueue::manageImport_WITH_LOCK(h256 const& _h, Transactio if (_transaction.gasPrice() < (*t->second).transaction.gasPrice()) return ImportResult::OverbidGasPrice; else - remove_WITH_LOCK((*t->second).transaction.sha3()); + { + h256 dropped = (*t->second).transaction.sha3(); + remove_WITH_LOCK(dropped); + m_onReplaced(dropped); + } } } auto fs = m_future.find(_transaction.from()); diff --git a/libethereum/TransactionQueue.h b/libethereum/TransactionQueue.h index f6c140e6f..9c8283aa2 100644 --- a/libethereum/TransactionQueue.h +++ b/libethereum/TransactionQueue.h @@ -117,6 +117,9 @@ public: /// Register a handler that will be called once asynchronous verification is comeplte an transaction has been imported template Handler onImport(T const& _t) { return m_onImport.add(_t); } + /// Register a handler that will be called once asynchronous verification is comeplte an transaction has been imported + template Handler onReplaced(T const& _t) { return m_onReplaced.add(_t); } + private: /// Verified and imported transaction @@ -184,6 +187,7 @@ private: Signal<> m_onReady; ///< Called when a subsequent call to import transactions will return a non-empty container. Be nice and exit fast. Signal m_onImport; ///< Called for each import attempt. Arguments are result, transaction id an node id. Be nice and exit fast. + Signal m_onReplaced; ///< Called whan transction is dropped during a call to import() to make room for another transaction. unsigned m_limit; ///< Max number of pending transactions unsigned m_futureLimit; ///< Max number of future transactions unsigned m_futureSize = 0; ///< Current number of future transactions