github.com/aychain/blockbook@v0.1.1-0.20181121092459-6d1fc7e07c5b/db/txcache.go (about) 1 package db 2 3 import ( 4 "blockbook/bchain" 5 "blockbook/common" 6 7 "github.com/golang/glog" 8 ) 9 10 // TxCache is handle to TxCacheServer 11 type TxCache struct { 12 db *RocksDB 13 chain bchain.BlockChain 14 metrics *common.Metrics 15 is *common.InternalState 16 enabled bool 17 } 18 19 // NewTxCache creates new TxCache interface and returns its handle 20 func NewTxCache(db *RocksDB, chain bchain.BlockChain, metrics *common.Metrics, is *common.InternalState, enabled bool) (*TxCache, error) { 21 if !enabled { 22 glog.Info("txcache: disabled") 23 } 24 return &TxCache{ 25 db: db, 26 chain: chain, 27 metrics: metrics, 28 is: is, 29 enabled: enabled, 30 }, nil 31 } 32 33 // GetTransaction returns transaction either from RocksDB or if not present from blockchain 34 // it the transaction is confirmed, it is stored in the RocksDB 35 func (c *TxCache) GetTransaction(txid string) (*bchain.Tx, uint32, error) { 36 var tx *bchain.Tx 37 var h uint32 38 var err error 39 if c.enabled { 40 tx, h, err = c.db.GetTx(txid) 41 if err != nil { 42 return nil, 0, err 43 } 44 if tx != nil { 45 // number of confirmations is not stored in cache, they change all the time 46 _, bestheight, _ := c.is.GetSyncState() 47 tx.Confirmations = bestheight - h + 1 48 c.metrics.TxCacheEfficiency.With(common.Labels{"status": "hit"}).Inc() 49 return tx, h, nil 50 } 51 } 52 tx, err = c.chain.GetTransaction(txid) 53 if err != nil { 54 return nil, 0, err 55 } 56 c.metrics.TxCacheEfficiency.With(common.Labels{"status": "miss"}).Inc() 57 // cache only confirmed transactions 58 if tx.Confirmations > 0 { 59 ta, err := c.db.GetTxAddresses(txid) 60 if err != nil { 61 return nil, 0, err 62 } 63 // the transaction may me not yet indexed, in that case get the height from the backend 64 if ta == nil { 65 h, err = c.chain.GetBestBlockHeight() 66 if err != nil { 67 return nil, 0, err 68 } 69 } else { 70 h = ta.Height 71 } 72 if c.enabled { 73 err = c.db.PutTx(tx, h, tx.Blocktime) 74 // do not return caching error, only log it 75 if err != nil { 76 glog.Error("PutTx error ", err) 77 } 78 } 79 } else { 80 h = 0 81 } 82 return tx, h, nil 83 }