gitlab.com/SiaPrime/SiaPrime@v1.4.1/modules/transactionpool/subscribe.go (about)

     1  package transactionpool
     2  
     3  import (
     4  	"gitlab.com/SiaPrime/SiaPrime/build"
     5  	"gitlab.com/SiaPrime/SiaPrime/encoding"
     6  	"gitlab.com/SiaPrime/SiaPrime/modules"
     7  	"gitlab.com/SiaPrime/SiaPrime/types"
     8  )
     9  
    10  // updateSubscribersTransactions sends a new transaction pool update to all
    11  // subscribers.
    12  func (tp *TransactionPool) updateSubscribersTransactions() {
    13  	diff := new(modules.TransactionPoolDiff)
    14  	// Create all of the diffs for reverted sets.
    15  	for id := range tp.subscriberSets {
    16  		// The transaction set is still in the transaction pool, no need to
    17  		// create an update.
    18  		_, exists := tp.transactionSets[id]
    19  		if exists {
    20  			continue
    21  		}
    22  
    23  		// Report that this set has been removed. Negative diffs don't have all
    24  		// fields filled out.
    25  		diff.RevertedTransactions = append(diff.RevertedTransactions, modules.TransactionSetID(id))
    26  	}
    27  
    28  	// Clear the subscriber sets map.
    29  	for _, revert := range diff.RevertedTransactions {
    30  		delete(tp.subscriberSets, TransactionSetID(revert))
    31  	}
    32  
    33  	// Create all of the diffs for sets that have been recently created.
    34  	for id, set := range tp.transactionSets {
    35  		_, exists := tp.subscriberSets[id]
    36  		if exists {
    37  			// The transaction set has already been sent in an update.
    38  			continue
    39  		}
    40  
    41  		// Report that this transaction set is new to the transaction pool.
    42  		ids := make([]types.TransactionID, 0, len(set))
    43  		sizes := make([]uint64, 0, len(set))
    44  		for i := range set {
    45  			encodedTxn := encoding.Marshal(set[i])
    46  			sizes = append(sizes, uint64(len(encodedTxn)))
    47  			ids = append(ids, set[i].ID())
    48  		}
    49  		ut := &modules.UnconfirmedTransactionSet{
    50  			Change: tp.transactionSetDiffs[id],
    51  			ID:     modules.TransactionSetID(id),
    52  
    53  			IDs:          ids,
    54  			Sizes:        sizes,
    55  			Transactions: set,
    56  		}
    57  		// Add this diff to our set of subscriber diffs.
    58  		tp.subscriberSets[id] = ut
    59  		diff.AppliedTransactions = append(diff.AppliedTransactions, ut)
    60  	}
    61  
    62  	for _, subscriber := range tp.subscribers {
    63  		subscriber.ReceiveUpdatedUnconfirmedTransactions(diff)
    64  	}
    65  }
    66  
    67  // TransactionPoolSubscribe adds a subscriber to the transaction pool.
    68  // Subscribers will receive the full transaction set every time there is a
    69  // significant change to the transaction pool.
    70  func (tp *TransactionPool) TransactionPoolSubscribe(subscriber modules.TransactionPoolSubscriber) {
    71  	tp.mu.Lock()
    72  	defer tp.mu.Unlock()
    73  
    74  	// Check that this subscriber is not already subscribed.
    75  	for _, s := range tp.subscribers {
    76  		if s == subscriber {
    77  			build.Critical("refusing to double-subscribe subscriber")
    78  		}
    79  	}
    80  
    81  	// Add the subscriber to the subscriber list.
    82  	tp.subscribers = append(tp.subscribers, subscriber)
    83  
    84  	// Send the new subscriber the transaction pool set.
    85  	diff := new(modules.TransactionPoolDiff)
    86  	diff.AppliedTransactions = make([]*modules.UnconfirmedTransactionSet, 0, len(tp.subscriberSets))
    87  	for _, ut := range tp.subscriberSets {
    88  		diff.AppliedTransactions = append(diff.AppliedTransactions, ut)
    89  	}
    90  	subscriber.ReceiveUpdatedUnconfirmedTransactions(diff)
    91  }
    92  
    93  // Unsubscribe removes a subscriber from the transaction pool. If the
    94  // subscriber is not in tp.subscribers, Unsubscribe does nothing. If the
    95  // subscriber occurs more than once in tp.subscribers, only the earliest
    96  // occurrence is removed (unsubscription fails).
    97  func (tp *TransactionPool) Unsubscribe(subscriber modules.TransactionPoolSubscriber) {
    98  	tp.mu.Lock()
    99  	defer tp.mu.Unlock()
   100  
   101  	// Search for and remove subscriber from list of subscribers.
   102  	for i := range tp.subscribers {
   103  		if tp.subscribers[i] == subscriber {
   104  			tp.subscribers = append(tp.subscribers[0:i], tp.subscribers[i+1:]...)
   105  			break
   106  		}
   107  	}
   108  }