@ -42,39 +42,84 @@ struct TransactionQueueChannel: public LogChannel { static const char* name(); s
struct TransactionQueueTraceChannel : public LogChannel { static const char * name ( ) ; static const int verbosity = 7 ; } ;
# define ctxq dev::LogOutputStream<dev::eth::TransactionQueueTraceChannel, true>()
enum class IfDropped { Ignore , Retry } ;
/// Import transaction policy
enum class IfDropped
{
Ignore , ///< Don't import transaction that was previously dropped.
Retry ///< Import transaction even if it was dropped before.
} ;
/**
* @ brief A queue of Transactions , each stored as RLP .
* Maintains a transaction queue sorted by nonce diff and gas price
* Maintains a transaction queue sorted by nonce diff and gas price .
* @ threadsafe
*/
class TransactionQueue
{
public :
/// @brief TransactionQueue
/// @param _limit Maximum number of pending transactions in the queue
/// @param _futureLimit Maximum number of future nonce transactions
/// @param _limit Maximum number of pending transactions in the queue.
/// @param _futureLimit Maximum number of future nonce transactions.
TransactionQueue ( unsigned _limit = 1024 , unsigned _futureLimit = 1024 ) ;
~ TransactionQueue ( ) ;
/// Add transaction to the queue to be verified and imported.
/// @param _data RLP encoded transaction data.
/// @param _nodeId Optional network identified of a node transaction comes from.
void enqueue ( RLP const & _data , h512 const & _nodeId ) ;
/// Verify and add transaction to the queue synchronously.
/// @param _tx RLP encoded transaction data.
/// @param _ik Set to Retry to force re-addinga transaction that was previously dropped.
/// @returns Import result code.
ImportResult import ( bytes const & _tx , IfDropped _ik = IfDropped : : Ignore ) { return import ( & _tx , _ik ) ; }
/// Verify and add transaction to the queue synchronously.
/// @param _tx Trasnaction data.
/// @param _ik Set to Retry to force re-addinga transaction that was previously dropped.
/// @returns Import result code.
ImportResult import ( Transaction const & _tx , IfDropped _ik = IfDropped : : Ignore ) ;
/// Remove transaction from the queue
/// @param _txHash Trasnaction hash
void drop ( h256 const & _txHash ) ;
/// Get number of pending transactions for account.
/// @returns Pending transaction count.
unsigned waiting ( Address const & _a ) const ;
/// Get top transactions from the queue. Returned transactions are not removed from the queue automatically.
/// @param _limit Max number of transactions to return.
/// @returns up to _limit transactions ordered by nonce and gas price.
Transactions topTransactions ( unsigned _limit ) const ;
/// Get a hash set of transactions in the queue
/// @returns A hash set of all transactions in the queue
h256Hash knownTransactions ( ) const ;
/// Get max nonce for an account
/// @returns Max transaction nonce for account in the queue
u256 maxNonce ( Address const & _a ) const ;
/// Mark transaction as future. It wont be retured in topTransactions list until a transaction with a preceeding nonce is imported or marked with dropGood
/// @param _t Transaction hash
void setFuture ( h256 const & _t ) ;
/// Drop a trasnaction from the list if exists and move following future trasnactions to current (if any)
/// @param _t Transaction hash
void dropGood ( Transaction const & _t ) ;
/// Clear the queue
void clear ( ) ;
/// Register a handler that will be called once there is a new transaction imported
template < class T > Handler < > onReady ( T const & _t ) { return m_onReady . add ( _t ) ; }
/// Register a handler that will be called once asynchronous verification is comeplte an transaction has been imported
template < class T > Handler < ImportResult , h256 const & , h512 const & > onImport ( T const & _t ) { return m_onImport . add ( _t ) ; }
private :
/// Verified and imported transaction
struct VerifiedTransaction
{
VerifiedTransaction ( Transaction const & _t ) : transaction ( _t ) { }
@ -83,9 +128,10 @@ private:
VerifiedTransaction ( VerifiedTransaction const & ) = delete ;
VerifiedTransaction & operator = ( VerifiedTransaction const & ) = delete ;
Transaction transaction ;
Transaction transaction ; ///< Transaction data
} ;
/// Trasnaction pending verification
struct UnverifiedTransaction
{
UnverifiedTransaction ( ) { }
@ -96,13 +142,14 @@ private:
UnverifiedTransaction ( UnverifiedTransaction const & ) = delete ;
UnverifiedTransaction & operator = ( UnverifiedTransaction const & ) = delete ;
bytes transaction ;
h512 nodeId ;
bytes transaction ; ///< RLP encoded transaction data
h512 nodeId ; ///< Network Id of the peer transaction comes from
} ;
struct PriorityCompare
{
TransactionQueue & queue ;
/// Compare transaction by nonce height and gas price.
bool operator ( ) ( VerifiedTransaction const & _first , VerifiedTransaction const & _second ) const
{
u256 const & height1 = _first . transaction . nonce ( ) - queue . m_currentByAddressAndNonce [ _first . transaction . sender ( ) ] . begin ( ) - > first ;