Select the types of activity you want to include in your feed.
Fix multiple DID bloom filter bugs
- Force recreate filter after snapshot application, to avoid inconsistent state as cometbft transitions to block sync / consensus - Don't save 0xffffffffffffffff bloom filter seq when there are no operations
···189189190190 if d.snapshotApplier.Done() {
191191 d.snapshotApplier = nil
192192+ err = d.txFactory.RecreateDIDBloomFilter()
193193+ if err != nil {
194194+ return nil, stacktrace.Propagate(err)
195195+ }
192196 }
193197194198 // this is a giant hack but I found no other way to not make the machine run out of space as it applies a snapshot
-2
main.go
···9393 if err != nil {
9494 log.Fatalf("failed to drop application index database: %v", err)
9595 }
9696-9797- os.Remove(didBloomFilterPath)
9896 }
999710098 mempoolSubmitter := &txSubmitter{}
+3-3
store/did_bloom.go
···34343535var _ transaction.BloomFilterStorage = (*DIDBloomFilterStore)(nil)
36363737-func (s *DIDBloomFilterStore) BuildDIDBloomFilter(tx transaction.Read) (*bloom.BloomFilter, error) {
3737+func (s *DIDBloomFilterStore) BuildDIDBloomFilter(tx transaction.Read, forceRecreate bool) (*bloom.BloomFilter, error) {
3838 filter, estimatedDIDCount, err := func() (*bloom.BloomFilter, uint64, error) {
3939- if s.filePath == "" {
3939+ if s.filePath == "" || forceRecreate {
4040 return nil, 0, nil
4141 }
4242 var f bloom.BloomFilter
···9797 return filter, nil
9898 }
9999100100- filterEstimatedItems := uint(100000000) // we know there are like 80M DIDs at the time of writing
100100+ filterEstimatedItems := uint(150000000) // we know there are like 80M DIDs at the time of writing
101101 if estimatedDIDCount != 0 {
102102 filterEstimatedItems = max(filterEstimatedItems, uint(estimatedDIDCount*3))
103103 }
+50-4
transaction/factory.go
···2121}
22222323type BloomFilterStorage interface {
2424- BuildDIDBloomFilter(tx Read) (*bloom.BloomFilter, error)
2424+ BuildDIDBloomFilter(tx Read, forceRecreate bool) (*bloom.BloomFilter, error)
2525 StoreDIDBloomFilter(writeBloomTo func(w io.Writer) (uint64, uint64, uint64, error)) error
2626}
2727···5454 // in practice we just want to blindly list all DIDs "past present and future", so it doesn't matter what the version is
5555 // (when doing historical queries, it's fine if the bloom filter claims that a DID already exists when it might not exist yet)
5656 tx := f.ReadWorking(time.Now())
5757- f.bloomFilter, err = bloomFilterStorage.BuildDIDBloomFilter(tx)
5757+ f.bloomFilter, err = bloomFilterStorage.BuildDIDBloomFilter(tx, false)
5858 if err != nil {
5959 return nil, stacktrace.Propagate(err)
6060 }
6161 f.bloomSeq, err = f.operationCounter(tx)
6262+ if err != nil {
6363+ return nil, stacktrace.Propagate(err)
6464+ }
6265 // since the sequenceGetter always returns the next sequence
6363- f.bloomSeq--
6666+ if f.bloomSeq > 0 {
6767+ f.bloomSeq--
6868+ }
6969+7070+ err = f.SaveDIDBloomFilter()
6471 return f, stacktrace.Propagate(err)
6572}
6673···100107 return nil, stacktrace.Propagate(err)
101108 }
102109 // give the reader an empty tree just to satisfy expectations
103103- tmpTree := iavl.NewMutableTree(db.NewMemDB(), 1, false, iavl.NewNopLogger())
110110+ tmpTree := iavl.NewMutableTree(db.NewMemDB(), 1, true, iavl.NewNopLogger())
104111 _, v, err := tmpTree.SaveVersion()
105112 if err != nil {
106113 return nil, stacktrace.Propagate(err)
···132139func (f *Factory) SaveDIDBloomFilter() error {
133140 f.bloomSaverMu.Lock()
134141 defer f.bloomSaverMu.Unlock()
142142+ return stacktrace.Propagate(f.saveDIDBloomFilterWithinMutex())
143143+}
135144145145+func (f *Factory) saveDIDBloomFilterWithinMutex() error {
136146 f.bloomMu.RLock()
137147 shouldSave := f.bloomSeq > f.bloomLastSaveSeq
138148 f.bloomMu.RUnlock()
···172182173183 return nil
174184}
185185+186186+func (f *Factory) RecreateDIDBloomFilter() error {
187187+ f.bloomSaverMu.Lock()
188188+ defer f.bloomSaverMu.Unlock()
189189+190190+ var err error
191191+ err = func() error {
192192+ f.bloomMu.Lock()
193193+ defer f.bloomMu.Unlock()
194194+ // if we use ReadCommitted, it's going to fail when the tree doesn't have versions yet
195195+ // in practice we just want to blindly list all DIDs "past present and future", so it doesn't matter what the version is
196196+ // (when doing historical queries, it's fine if the bloom filter claims that a DID already exists when it might not exist yet)
197197+ tx := f.ReadWorking(time.Now())
198198+ f.bloomFilter, err = f.bloomFilterStorage.BuildDIDBloomFilter(tx, true)
199199+ if err != nil {
200200+ return stacktrace.Propagate(err)
201201+ }
202202+ f.bloomSeq, err = f.operationCounter(tx)
203203+ if err != nil {
204204+ return stacktrace.Propagate(err)
205205+ }
206206+ // since the sequenceGetter always returns the next sequence
207207+ if f.bloomSeq > 0 {
208208+ f.bloomSeq--
209209+ }
210210+211211+ f.bloomLastSaveSeq = 0
212212+ return nil
213213+ }()
214214+ if err != nil {
215215+ return stacktrace.Propagate(err)
216216+ }
217217+218218+ err = f.saveDIDBloomFilterWithinMutex()
219219+ return stacktrace.Propagate(err)
220220+}