github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/storage/badger/epoch_commits.go (about) 1 package badger 2 3 import ( 4 "fmt" 5 6 "github.com/dgraph-io/badger/v2" 7 8 "github.com/onflow/flow-go/model/flow" 9 "github.com/onflow/flow-go/module" 10 "github.com/onflow/flow-go/module/metrics" 11 "github.com/onflow/flow-go/storage/badger/operation" 12 "github.com/onflow/flow-go/storage/badger/transaction" 13 ) 14 15 type EpochCommits struct { 16 db *badger.DB 17 cache *Cache[flow.Identifier, *flow.EpochCommit] 18 } 19 20 func NewEpochCommits(collector module.CacheMetrics, db *badger.DB) *EpochCommits { 21 22 store := func(id flow.Identifier, commit *flow.EpochCommit) func(*transaction.Tx) error { 23 return transaction.WithTx(operation.SkipDuplicates(operation.InsertEpochCommit(id, commit))) 24 } 25 26 retrieve := func(id flow.Identifier) func(*badger.Txn) (*flow.EpochCommit, error) { 27 return func(tx *badger.Txn) (*flow.EpochCommit, error) { 28 var commit flow.EpochCommit 29 err := operation.RetrieveEpochCommit(id, &commit)(tx) 30 return &commit, err 31 } 32 } 33 34 ec := &EpochCommits{ 35 db: db, 36 cache: newCache[flow.Identifier, *flow.EpochCommit](collector, metrics.ResourceEpochCommit, 37 withLimit[flow.Identifier, *flow.EpochCommit](4*flow.DefaultTransactionExpiry), 38 withStore(store), 39 withRetrieve(retrieve)), 40 } 41 42 return ec 43 } 44 45 func (ec *EpochCommits) StoreTx(commit *flow.EpochCommit) func(*transaction.Tx) error { 46 return ec.cache.PutTx(commit.ID(), commit) 47 } 48 49 func (ec *EpochCommits) retrieveTx(commitID flow.Identifier) func(tx *badger.Txn) (*flow.EpochCommit, error) { 50 return func(tx *badger.Txn) (*flow.EpochCommit, error) { 51 val, err := ec.cache.Get(commitID)(tx) 52 if err != nil { 53 return nil, fmt.Errorf("could not retrieve EpochCommit event with id %x: %w", commitID, err) 54 } 55 return val, nil 56 } 57 } 58 59 // TODO: can we remove this method? Its not contained in the interface. 60 func (ec *EpochCommits) Store(commit *flow.EpochCommit) error { 61 return operation.RetryOnConflictTx(ec.db, transaction.Update, ec.StoreTx(commit)) 62 } 63 64 // ByID will return the EpochCommit event by its ID. 65 // Error returns: 66 // * storage.ErrNotFound if no EpochCommit with the ID exists 67 func (ec *EpochCommits) ByID(commitID flow.Identifier) (*flow.EpochCommit, error) { 68 tx := ec.db.NewTransaction(false) 69 defer tx.Discard() 70 return ec.retrieveTx(commitID)(tx) 71 }