github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/storage/badger/transactions.go (about)

     1  package badger
     2  
     3  import (
     4  	"github.com/dgraph-io/badger/v2"
     5  
     6  	"github.com/onflow/flow-go/model/flow"
     7  	"github.com/onflow/flow-go/module"
     8  	"github.com/onflow/flow-go/module/metrics"
     9  	"github.com/onflow/flow-go/storage/badger/operation"
    10  	"github.com/onflow/flow-go/storage/badger/transaction"
    11  )
    12  
    13  // Transactions ...
    14  type Transactions struct {
    15  	db    *badger.DB
    16  	cache *Cache[flow.Identifier, *flow.TransactionBody]
    17  }
    18  
    19  // NewTransactions ...
    20  func NewTransactions(cacheMetrics module.CacheMetrics, db *badger.DB) *Transactions {
    21  	store := func(txID flow.Identifier, flowTX *flow.TransactionBody) func(*transaction.Tx) error {
    22  		return transaction.WithTx(operation.SkipDuplicates(operation.InsertTransaction(txID, flowTX)))
    23  	}
    24  
    25  	retrieve := func(txID flow.Identifier) func(tx *badger.Txn) (*flow.TransactionBody, error) {
    26  		return func(tx *badger.Txn) (*flow.TransactionBody, error) {
    27  			var flowTx flow.TransactionBody
    28  			err := operation.RetrieveTransaction(txID, &flowTx)(tx)
    29  			return &flowTx, err
    30  		}
    31  	}
    32  
    33  	t := &Transactions{
    34  		db: db,
    35  		cache: newCache[flow.Identifier, *flow.TransactionBody](cacheMetrics, metrics.ResourceTransaction,
    36  			withLimit[flow.Identifier, *flow.TransactionBody](flow.DefaultTransactionExpiry+100),
    37  			withStore(store),
    38  			withRetrieve(retrieve)),
    39  	}
    40  
    41  	return t
    42  }
    43  
    44  // Store ...
    45  func (t *Transactions) Store(flowTx *flow.TransactionBody) error {
    46  	return operation.RetryOnConflictTx(t.db, transaction.Update, t.storeTx(flowTx))
    47  }
    48  
    49  // ByID ...
    50  func (t *Transactions) ByID(txID flow.Identifier) (*flow.TransactionBody, error) {
    51  	tx := t.db.NewTransaction(false)
    52  	defer tx.Discard()
    53  	return t.retrieveTx(txID)(tx)
    54  }
    55  
    56  func (t *Transactions) storeTx(flowTx *flow.TransactionBody) func(*transaction.Tx) error {
    57  	return t.cache.PutTx(flowTx.ID(), flowTx)
    58  }
    59  
    60  func (t *Transactions) retrieveTx(txID flow.Identifier) func(*badger.Txn) (*flow.TransactionBody, error) {
    61  	return func(tx *badger.Txn) (*flow.TransactionBody, error) {
    62  		val, err := t.cache.Get(txID)(tx)
    63  		if err != nil {
    64  			return nil, err
    65  		}
    66  		return val, err
    67  	}
    68  }