github.com/unicornultrafoundation/go-u2u@v1.0.0-rc1.0.20240205080301-e74a83d3fadc/topicsdb/topicsdb.go (about)

     1  package topicsdb
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	"github.com/unicornultrafoundation/go-helios/native/idx"
     8  	"github.com/unicornultrafoundation/go-helios/u2udb"
     9  	"github.com/unicornultrafoundation/go-u2u/common"
    10  	"github.com/unicornultrafoundation/go-u2u/core/types"
    11  )
    12  
    13  const maxTopicsCount = 5 // count is limited hard to 5 by EVM (see LOG0...LOG4 ops)
    14  
    15  var (
    16  	ErrEmptyTopics  = fmt.Errorf("empty topics")
    17  	ErrTooBigTopics = fmt.Errorf("too many topics")
    18  )
    19  
    20  // Index is a specialized indexes for log records storing and fetching.
    21  type Index interface {
    22  	FindInBlocks(ctx context.Context, from, to idx.Block, pattern [][]common.Hash) (logs []*types.Log, err error)
    23  	ForEachInBlocks(ctx context.Context, from, to idx.Block, pattern [][]common.Hash, onLog func(*types.Log) (gonext bool)) error
    24  	Push(recs ...*types.Log) error
    25  	Close()
    26  
    27  	WrapTablesAsBatched() (unwrap func())
    28  }
    29  
    30  // New Index instance.
    31  func New(dbs u2udb.DBProducer) Index {
    32  	tt := newIndex(dbs)
    33  
    34  	return tt
    35  }
    36  
    37  // New Index instance consumes limited threads count.
    38  func NewWithThreadPool(dbs u2udb.DBProducer) Index {
    39  	tt := newIndex(dbs)
    40  	return &withThreadPool{tt}
    41  }
    42  
    43  func limitPattern(pattern [][]common.Hash) (limited [][]common.Hash, err error) {
    44  	if len(pattern) > (maxTopicsCount + 1) {
    45  		limited = make([][]common.Hash, (maxTopicsCount + 1))
    46  	} else {
    47  		limited = make([][]common.Hash, len(pattern))
    48  	}
    49  	copy(limited, pattern)
    50  
    51  	ok := false
    52  	for i, variants := range limited {
    53  		ok = ok || len(variants) > 0
    54  		if len(variants) > 1 {
    55  			limited[i] = uniqOnly(variants)
    56  		}
    57  	}
    58  	if !ok {
    59  		err = ErrEmptyTopics
    60  		return
    61  	}
    62  
    63  	return
    64  }
    65  
    66  func uniqOnly(hh []common.Hash) []common.Hash {
    67  	index := make(map[common.Hash]struct{}, len(hh))
    68  	for _, h := range hh {
    69  		index[h] = struct{}{}
    70  	}
    71  
    72  	uniq := make([]common.Hash, 0, len(index))
    73  	for h := range index {
    74  		uniq = append(uniq, h)
    75  	}
    76  	return uniq
    77  }