package transaction import ( "sync" "time" "github.com/bits-and-blooms/bloom/v3" "github.com/cosmos/iavl" "github.com/gbl08ma/stacktrace" ) type readTx struct { ts time.Time height int64 mutableTree *iavl.MutableTree // only present if upgradable tree ReadTree db ExtendedDB bloomMu *sync.RWMutex bloomFilter *bloom.BloomFilter bloomSeq *uint64 operationCounter func(tx Read) (uint64, error) } // Height implements [Read]. func (t *readTx) Height() int64 { return t.height } // Timestamp implements [Read]. func (t *readTx) Timestamp() time.Time { return t.ts } // CountOperations implements [Read]. func (t *readTx) CountOperations() (uint64, error) { count, err := t.operationCounter(t) return count, stacktrace.Propagate(err) } // Tree implements [Read]. func (t *readTx) Tree() ReadTree { if t.mutableTree != nil { return t.mutableTree } return t.tree } // IndexDB implements [Read]. func (t *readTx) IndexDB() IndexReader { return t.db } // TestDIDBloomFilter implements [Read]. func (t *readTx) TestDIDBloomFilter(did []byte) bool { t.bloomMu.RLock() defer t.bloomMu.RUnlock() return t.bloomFilter.Test(did) } // Upgrade implements [Read]. func (t *readTx) Upgrade() (Write, error) { if t.mutableTree == nil { return nil, stacktrace.NewError("historical transaction is not upgradable to a write transaction") } return &writeTx{ readTx: t, unsavedBloomAdditions: map[string]struct{}{}, }, nil } // UpgradeForIndexOnly implements [Read]. func (t *readTx) UpgradeForIndexOnly() (WriteIndex, error) { return &writeIndexTx{ db: t.db, }, nil }