github.com/unicornultrafoundation/go-u2u@v1.0.0-rc1.0.20240205080301-e74a83d3fadc/gossip/dummy_tx_pool.go (about)

     1  package gossip
     2  
     3  import (
     4  	"math/rand"
     5  	"sort"
     6  	"sync"
     7  
     8  	"github.com/unicornultrafoundation/go-u2u/common"
     9  	"github.com/unicornultrafoundation/go-u2u/core/types"
    10  	notify "github.com/unicornultrafoundation/go-u2u/event"
    11  
    12  	"github.com/unicornultrafoundation/go-u2u/evmcore"
    13  )
    14  
    15  // dummyTxPool is a fake, helper transaction pool for testing purposes
    16  type dummyTxPool struct {
    17  	txFeed notify.Feed
    18  	pool   []*types.Transaction        // Collection of all transactions
    19  	added  chan<- []*types.Transaction // Notification channel for new transactions
    20  
    21  	signer types.Signer
    22  
    23  	lock sync.RWMutex // Protects the transaction pool
    24  }
    25  
    26  // AddRemotes appends a batch of transactions to the pool, and notifies any
    27  // listeners if the addition channel is non nil
    28  func (p *dummyTxPool) AddRemotes(txs []*types.Transaction) []error {
    29  	p.lock.Lock()
    30  	defer p.lock.Unlock()
    31  
    32  	p.pool = append(p.pool, txs...)
    33  	if p.added != nil {
    34  		p.added <- txs
    35  	}
    36  	return make([]error, len(txs))
    37  }
    38  
    39  func (p *dummyTxPool) AddLocals(txs []*types.Transaction) []error {
    40  	return p.AddRemotes(txs)
    41  }
    42  
    43  func (p *dummyTxPool) AddLocal(tx *types.Transaction) error {
    44  	return p.AddLocals([]*types.Transaction{tx})[0]
    45  }
    46  
    47  func (p *dummyTxPool) Nonce(addr common.Address) uint64 {
    48  	return 0
    49  }
    50  
    51  func (p *dummyTxPool) Stats() (int, int) {
    52  	return p.Count(), 0
    53  }
    54  
    55  func (p *dummyTxPool) Content() (map[common.Address]types.Transactions, map[common.Address]types.Transactions) {
    56  	return nil, nil
    57  }
    58  
    59  func (p *dummyTxPool) ContentFrom(addr common.Address) (types.Transactions, types.Transactions) {
    60  	return nil, nil
    61  }
    62  
    63  // Pending returns all the transactions known to the pool
    64  func (p *dummyTxPool) Pending(enforceTips bool) (map[common.Address]types.Transactions, error) {
    65  	p.lock.RLock()
    66  	defer p.lock.RUnlock()
    67  
    68  	batches := make(map[common.Address]types.Transactions)
    69  	for _, tx := range p.pool {
    70  		from, _ := types.Sender(p.signer, tx)
    71  		batches[from] = append(batches[from], tx)
    72  	}
    73  	for _, batch := range batches {
    74  		sort.Sort(types.TxByNonce(batch))
    75  	}
    76  	return batches, nil
    77  }
    78  
    79  func (p *dummyTxPool) SubscribeNewTxsNotify(ch chan<- evmcore.NewTxsNotify) notify.Subscription {
    80  	return p.txFeed.Subscribe(ch)
    81  }
    82  
    83  func (p *dummyTxPool) Map() map[common.Hash]*types.Transaction {
    84  	p.lock.RLock()
    85  	defer p.lock.RUnlock()
    86  	res := make(map[common.Hash]*types.Transaction, len(p.pool))
    87  	for _, tx := range p.pool {
    88  		res[tx.Hash()] = tx
    89  	}
    90  	return nil
    91  }
    92  
    93  func (p *dummyTxPool) Get(txid common.Hash) *types.Transaction {
    94  	p.lock.RLock()
    95  	defer p.lock.RUnlock()
    96  	for _, tx := range p.pool {
    97  		if tx.Hash() == txid {
    98  			return tx
    99  		}
   100  	}
   101  	return nil
   102  }
   103  
   104  func (p *dummyTxPool) Has(txid common.Hash) bool {
   105  	p.lock.RLock()
   106  	defer p.lock.RUnlock()
   107  	for _, tx := range p.pool {
   108  		if tx.Hash() == txid {
   109  			return true
   110  		}
   111  	}
   112  	return false
   113  }
   114  
   115  func (p *dummyTxPool) OnlyNotExisting(txids []common.Hash) []common.Hash {
   116  	m := p.Map()
   117  	notExisting := make([]common.Hash, 0, len(txids))
   118  	for _, txid := range txids {
   119  		if m[txid] == nil {
   120  			notExisting = append(notExisting, txid)
   121  		}
   122  	}
   123  	return notExisting
   124  }
   125  
   126  func (p *dummyTxPool) SampleHashes(max int) []common.Hash {
   127  	p.lock.RLock()
   128  	defer p.lock.RUnlock()
   129  	res := make([]common.Hash, 0, max)
   130  	skip := 0
   131  	if len(p.pool) > max {
   132  		skip = rand.Intn(len(p.pool) - max)
   133  	}
   134  	for _, tx := range p.pool {
   135  		if len(res) >= max {
   136  			break
   137  		}
   138  		if skip > 0 {
   139  			skip--
   140  			continue
   141  		}
   142  		res = append(res, tx.Hash())
   143  	}
   144  	return res
   145  }
   146  
   147  func (p *dummyTxPool) Count() int {
   148  	return len(p.pool)
   149  }
   150  
   151  func (p *dummyTxPool) Clear() {
   152  	p.lock.Lock()
   153  	defer p.lock.Unlock()
   154  	if len(p.pool) != 0 {
   155  		p.pool = p.pool[:0]
   156  	}
   157  }
   158  
   159  func (p *dummyTxPool) Delete(needle common.Hash) {
   160  	p.lock.Lock()
   161  	defer p.lock.Unlock()
   162  	notErased := make([]*types.Transaction, 0, len(p.pool)-1)
   163  	for _, tx := range p.pool {
   164  		if tx.Hash() != needle {
   165  			notErased = append(notErased, tx)
   166  		}
   167  	}
   168  	p.pool = notErased
   169  }