Ethereum  PoC-8
The C++ Implementation of Ethereum
TransactionQueue.h
Go to the documentation of this file.
1 /*
2  This file is part of cpp-ethereum.
3 
4  cpp-ethereum is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  cpp-ethereum is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
16 */
22 #pragma once
23 
24 #include <functional>
25 #include <condition_variable>
26 #include <thread>
27 #include <deque>
28 #include <libdevcore/Common.h>
29 #include <libdevcore/Guards.h>
30 #include <libdevcore/Log.h>
31 #include <libethcore/Common.h>
32 #include "Transaction.h"
33 
34 namespace dev
35 {
36 namespace eth
37 {
38 
45 {
46 public:
47  struct Limits { size_t current; size_t future; };
48 
52  TransactionQueue(unsigned _limit = 1024, unsigned _futureLimit = 1024);
53  TransactionQueue(Limits const& _l): TransactionQueue(_l.current, _l.future) {}
58  void enqueue(RLP const& _data, h512 const& _nodeId);
59 
64  ImportResult import(bytes const& _tx, IfDropped _ik = IfDropped::Ignore) { return import(&_tx, _ik); }
65 
70  ImportResult import(Transaction const& _tx, IfDropped _ik = IfDropped::Ignore);
71 
74  void drop(h256 const& _txHash);
75 
78  unsigned waiting(Address const& _a) const;
79 
84  Transactions topTransactions(unsigned _limit, h256Hash const& _avoid = h256Hash()) const;
85 
89 
92  u256 maxNonce(Address const& _a) const;
93 
96  void setFuture(h256 const& _t);
97 
100  void dropGood(Transaction const& _t);
101 
102  struct Status
103  {
104  size_t current;
105  size_t future;
106  size_t unverified;
107  size_t dropped;
108  };
110  Status status() const { Status ret; DEV_GUARDED(x_queue) { ret.unverified = m_unverified.size(); } ReadGuard l(m_lock); ret.dropped = m_dropped.size(); ret.current = m_currentByHash.size(); ret.future = m_future.size(); return ret; }
111 
113  Limits limits() const { return Limits{m_limit, m_futureLimit}; }
114 
116  void clear();
117 
119  template <class T> Handler<> onReady(T const& _t) { return m_onReady.add(_t); }
120 
122  template <class T> Handler<ImportResult, h256 const&, h512 const&> onImport(T const& _t) { return m_onImport.add(_t); }
123 
125  template <class T> Handler<h256 const&> onReplaced(T const& _t) { return m_onReplaced.add(_t); }
126 
127 private:
128 
130  struct VerifiedTransaction
131  {
132  VerifiedTransaction(Transaction const& _t): transaction(_t) {}
133  VerifiedTransaction(VerifiedTransaction&& _t): transaction(std::move(_t.transaction)) {}
134 
135  VerifiedTransaction(VerifiedTransaction const&) = delete;
136  VerifiedTransaction& operator=(VerifiedTransaction const&) = delete;
137 
138  Transaction transaction;
139  };
140 
142  struct UnverifiedTransaction
143  {
144  UnverifiedTransaction() {}
145  UnverifiedTransaction(bytesConstRef const& _t, h512 const& _nodeId): transaction(_t.toBytes()), nodeId(_nodeId) {}
146  UnverifiedTransaction(UnverifiedTransaction&& _t): transaction(std::move(_t.transaction)), nodeId(std::move(_t.nodeId)) {}
147  UnverifiedTransaction& operator=(UnverifiedTransaction&& _other)
148  {
149  assert(&_other != this);
150 
151  transaction = std::move(_other.transaction);
152  nodeId = std::move(_other.nodeId);
153  return *this;
154  }
155 
156  UnverifiedTransaction(UnverifiedTransaction const&) = delete;
157  UnverifiedTransaction& operator=(UnverifiedTransaction const&) = delete;
158 
159  bytes transaction;
160  h512 nodeId;
161  };
162 
163  struct PriorityCompare
164  {
165  TransactionQueue& queue;
167  bool operator()(VerifiedTransaction const& _first, VerifiedTransaction const& _second) const
168  {
169  u256 const& height1 = _first.transaction.nonce() - queue.m_currentByAddressAndNonce[_first.transaction.sender()].begin()->first;
170  u256 const& height2 = _second.transaction.nonce() - queue.m_currentByAddressAndNonce[_second.transaction.sender()].begin()->first;
171  return height1 < height2 || (height1 == height2 && _first.transaction.gasPrice() > _second.transaction.gasPrice());
172  }
173  };
174 
175  // Use a set with dynamic comparator for minmax priority queue. The comparator takes into account min account nonce. Updating it does not affect the order.
176  using PriorityQueue = std::multiset<VerifiedTransaction, PriorityCompare>;
177 
179  ImportResult check_WITH_LOCK(h256 const& _h, IfDropped _ik);
180  ImportResult manageImport_WITH_LOCK(h256 const& _h, Transaction const& _transaction);
181 
182  void insertCurrent_WITH_LOCK(std::pair<h256, Transaction> const& _p);
183  void makeCurrent_WITH_LOCK(Transaction const& _t);
184  bool remove_WITH_LOCK(h256 const& _txHash);
185  u256 maxNonce_WITH_LOCK(Address const& _a) const;
186  void verifierBody();
187 
188  mutable SharedMutex m_lock;
189  h256Hash m_known;
190 
191  std::unordered_map<h256, std::function<void(ImportResult)>> m_callbacks;
192  h256Hash m_dropped;
193 
194  PriorityQueue m_current;
195  std::unordered_map<h256, PriorityQueue::iterator> m_currentByHash;
196  std::unordered_map<Address, std::map<u256, PriorityQueue::iterator>> m_currentByAddressAndNonce;
197  std::unordered_map<Address, std::map<u256, VerifiedTransaction>> m_future;
198 
199  Signal<> m_onReady;
200  Signal<ImportResult, h256 const&, h512 const&> m_onImport;
201  Signal<h256 const&> m_onReplaced;
202  unsigned m_limit;
203  unsigned m_futureLimit;
204  unsigned m_futureSize = 0;
205 
206  std::condition_variable m_queueReady;
207  std::vector<std::thread> m_verifiers;
208  std::deque<UnverifiedTransaction> m_unverified;
209  mutable Mutex x_queue;
210  std::atomic<bool> m_aborting = {false};
211 
212  Logger m_logger{createLogger(VerbosityInfo, "tq")};
213  Logger m_loggerDetail{createLogger(VerbosityDebug, "tq")};
214 };
215 
216 }
217 }
218 
dev::eth::TransactionQueue::topTransactions
Transactions topTransactions(unsigned _limit, h256Hash const &_avoid=h256Hash()) const
Definition: TransactionQueue.cpp:102
dev::SharedMutex
boost::shared_mutex SharedMutex
Definition: Guards.h:39
dev::eth::TransactionQueue::knownTransactions
h256Hash knownTransactions() const
Definition: TransactionQueue.cpp:112
dev::eth::ImportResult
ImportResult
Definition: Common.h:97
dev::eth::Transaction
Encodes a transaction, ready to be exported to or freshly imported from RLP.
Definition: Transaction.h:86
dev::eth::TransactionQueue::Limits::current
size_t current
Definition: TransactionQueue.h:47
dev::eth::Transactions
std::vector< Transaction > Transactions
Nice name for vector of Transaction.
Definition: Transaction.h:122
dev::eth::TransactionQueue::enqueue
void enqueue(RLP const &_data, h512 const &_nodeId)
Definition: TransactionQueue.cpp:356
dev::eth::TransactionQueue::limits
Limits limits() const
Definition: TransactionQueue.h:113
dev::eth::TransactionQueue::TransactionQueue
TransactionQueue(unsigned _limit=1024, unsigned _futureLimit=1024)
TransactionQueue.
Definition: TransactionQueue.cpp:33
dev::eth::TransactionQueue::onReady
Handler onReady(T const &_t)
Register a handler that will be called once there is a new transaction imported.
Definition: TransactionQueue.h:119
dev::h256
FixedHash< 32 > h256
Definition: FixedHash.h:356
dev::eth::TransactionQueue::onImport
Handler< ImportResult, h256 const &, h512 const & > onImport(T const &_t)
Register a handler that will be called once asynchronous verification is comeplte an transaction has ...
Definition: TransactionQueue.h:122
dev::eth::TransactionQueue::Status::future
size_t future
Definition: TransactionQueue.h:105
dev::h512
FixedHash< 64 > h512
Definition: FixedHash.h:355
dev::FixedHash< 64 >
dev::VerbosityInfo
@ VerbosityInfo
Definition: Log.h:70
DEV_GUARDED
#define DEV_GUARDED(MUTEX)
Simple block guard. The expression/block following is guarded though the given mutex....
Definition: Guards.h:132
dev::eth::TransactionQueue::dropGood
void dropGood(Transaction const &_t)
Definition: TransactionQueue.cpp:335
dev::eth::TransactionQueue::status
Status status() const
Definition: TransactionQueue.h:110
Common.h
dev::eth::TransactionQueue::Status::unverified
size_t unverified
Definition: TransactionQueue.h:106
dev::h256Hash
std::unordered_set< h256 > h256Hash
Definition: FixedHash.h:365
dev::eth::TransactionQueue::Status
Definition: TransactionQueue.h:103
dev::Logger
boost::log::sources::severity_channel_logger<> Logger
Definition: Log.h:124
Common.h
dev::eth::TransactionQueue::Limits::future
size_t future
Definition: TransactionQueue.h:47
dev::eth::TransactionQueue::Limits
Definition: TransactionQueue.h:47
dev::eth::IfDropped
IfDropped
Import transaction policy.
Definition: Common.h:215
dev::bytes
std::vector< byte > bytes
Definition: Common.h:72
dev::createLogger
Logger createLogger(int _severity, std::string const &_channel)
Definition: Log.h:125
Transaction.h
dev::bytesConstRef
vector_ref< byte const > bytesConstRef
Definition: Common.h:74
dev::ReadGuard
boost::shared_lock< boost::shared_mutex > ReadGuard
Definition: Guards.h:44
dev::eth::TransactionQueue::~TransactionQueue
~TransactionQueue()
Definition: TransactionQueue.cpp:46
dev::eth::TransactionQueue
A queue of Transactions, each stored as RLP. Maintains a transaction queue sorted by nonce diff and g...
Definition: TransactionQueue.h:45
dev::eth::TransactionQueue::setFuture
void setFuture(h256 const &_t)
Definition: TransactionQueue.cpp:253
dev::eth::TransactionQueue::Status::dropped
size_t dropped
Definition: TransactionQueue.h:107
dev::VerbosityDebug
@ VerbosityDebug
Definition: Log.h:71
dev::Mutex
std::mutex Mutex
Definition: Guards.h:37
dev::eth::TransactionQueue::clear
void clear()
Clear the queue.
Definition: TransactionQueue.cpp:344
dev::eth::TransactionQueue::maxNonce
u256 maxNonce(Address const &_a) const
Definition: TransactionQueue.cpp:184
std
Definition: FixedHash.h:393
dev::eth::TransactionQueue::Status::current
size_t current
Definition: TransactionQueue.h:104
dev::u256
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void > > u256
Definition: Common.h:121
dev::eth::Signal::add
std::shared_ptr< HandlerAux > add(Callback const &_h)
Definition: Common.h:162
dev::eth::IfDropped::Ignore
@ Ignore
Don't import transaction that was previously dropped.
dev
Definition: Address.cpp:21
dev::eth::TransactionQueue::waiting
unsigned waiting(Address const &_a) const
Definition: TransactionQueue.cpp:240
dev::eth::Handler
std::shared_ptr< typename Signal< Args... >::HandlerAux > Handler
Definition: Common.h:181
Guards.h
dev::eth::TransactionQueue::drop
void drop(h256 const &_txHash)
Definition: TransactionQueue.cpp:323
dev::RLP
Definition: RLP.h:48
dev::Address
h160 Address
Definition: Address.h:30
Log.h
dev::eth::TransactionQueue::TransactionQueue
TransactionQueue(Limits const &_l)
Definition: TransactionQueue.h:53
dev::eth::TransactionQueue::onReplaced
Handler< h256 const & > onReplaced(T const &_t)
Register a handler that will be called once asynchronous verification is comeplte an transaction has ...
Definition: TransactionQueue.h:125