github.com/cerberus-wallet/blockbook@v0.3.2/bchain/basemempool.go (about) 1 package bchain 2 3 import ( 4 "sort" 5 "sync" 6 ) 7 8 type addrIndex struct { 9 addrDesc string 10 n int32 11 } 12 13 type txEntry struct { 14 addrIndexes []addrIndex 15 time uint32 16 } 17 18 type txidio struct { 19 txid string 20 io []addrIndex 21 } 22 23 // BaseMempool is mempool base handle 24 type BaseMempool struct { 25 chain BlockChain 26 mux sync.Mutex 27 txEntries map[string]txEntry 28 addrDescToTx map[string][]Outpoint 29 OnNewTxAddr OnNewTxAddrFunc 30 } 31 32 // GetTransactions returns slice of mempool transactions for given address 33 func (m *BaseMempool) GetTransactions(address string) ([]Outpoint, error) { 34 parser := m.chain.GetChainParser() 35 addrDesc, err := parser.GetAddrDescFromAddress(address) 36 if err != nil { 37 return nil, err 38 } 39 return m.GetAddrDescTransactions(addrDesc) 40 } 41 42 // GetAddrDescTransactions returns slice of mempool transactions for given address descriptor, in reverse order 43 func (m *BaseMempool) GetAddrDescTransactions(addrDesc AddressDescriptor) ([]Outpoint, error) { 44 m.mux.Lock() 45 defer m.mux.Unlock() 46 outpoints := m.addrDescToTx[string(addrDesc)] 47 rv := make([]Outpoint, len(outpoints)) 48 for i, j := len(outpoints)-1, 0; i >= 0; i-- { 49 rv[j] = outpoints[i] 50 j++ 51 } 52 return rv, nil 53 } 54 55 func (a MempoolTxidEntries) Len() int { return len(a) } 56 func (a MempoolTxidEntries) Swap(i, j int) { a[i], a[j] = a[j], a[i] } 57 func (a MempoolTxidEntries) Less(i, j int) bool { 58 // if the Time is equal, sort by txid to make the order defined 59 hi := a[i].Time 60 hj := a[j].Time 61 if hi == hj { 62 return a[i].Txid > a[j].Txid 63 } 64 // order in reverse 65 return hi > hj 66 } 67 68 // removeEntryFromMempool removes entry from mempool structs. The caller is responsible for locking! 69 func (m *BaseMempool) removeEntryFromMempool(txid string, entry txEntry) { 70 delete(m.txEntries, txid) 71 for _, si := range entry.addrIndexes { 72 outpoints, found := m.addrDescToTx[si.addrDesc] 73 if found { 74 newOutpoints := make([]Outpoint, 0, len(outpoints)-1) 75 for _, o := range outpoints { 76 if o.Txid != txid { 77 newOutpoints = append(newOutpoints, o) 78 } 79 } 80 if len(newOutpoints) > 0 { 81 m.addrDescToTx[si.addrDesc] = newOutpoints 82 } else { 83 delete(m.addrDescToTx, si.addrDesc) 84 } 85 } 86 } 87 } 88 89 // GetAllEntries returns all mempool entries sorted by fist seen time in descending order 90 func (m *BaseMempool) GetAllEntries() MempoolTxidEntries { 91 i := 0 92 m.mux.Lock() 93 entries := make(MempoolTxidEntries, len(m.txEntries)) 94 for txid, entry := range m.txEntries { 95 entries[i] = MempoolTxidEntry{ 96 Txid: txid, 97 Time: entry.time, 98 } 99 i++ 100 } 101 m.mux.Unlock() 102 sort.Sort(entries) 103 return entries 104 } 105 106 // GetTransactionTime returns first seen time of a transaction 107 func (m *BaseMempool) GetTransactionTime(txid string) uint32 { 108 m.mux.Lock() 109 e, found := m.txEntries[txid] 110 m.mux.Unlock() 111 if !found { 112 return 0 113 } 114 return e.time 115 }