github.com/koko1123/flow-go-1@v0.29.6/engine/access/rest/request/get_events.go (about)

     1  package request
     2  
     3  import (
     4  	"fmt"
     5  	"regexp"
     6  
     7  	"github.com/koko1123/flow-go-1/model/flow"
     8  )
     9  
    10  const eventTypeQuery = "type"
    11  const blockQuery = "block_ids"
    12  const MaxEventRequestHeightRange = 250
    13  
    14  type GetEvents struct {
    15  	StartHeight uint64
    16  	EndHeight   uint64
    17  	Type        string
    18  	BlockIDs    []flow.Identifier
    19  }
    20  
    21  func (g *GetEvents) Build(r *Request) error {
    22  	return g.Parse(
    23  		r.GetQueryParam(eventTypeQuery),
    24  		r.GetQueryParam(startHeightQuery),
    25  		r.GetQueryParam(endHeightQuery),
    26  		r.GetQueryParams(blockQuery),
    27  	)
    28  }
    29  
    30  func (g *GetEvents) Parse(rawType string, rawStart string, rawEnd string, rawBlockIDs []string) error {
    31  	var height Height
    32  	err := height.Parse(rawStart)
    33  	if err != nil {
    34  		return fmt.Errorf("invalid start height: %w", err)
    35  	}
    36  	g.StartHeight = height.Flow()
    37  	err = height.Parse(rawEnd)
    38  	if err != nil {
    39  		return fmt.Errorf("invalid end height: %w", err)
    40  	}
    41  	g.EndHeight = height.Flow()
    42  
    43  	var blockIDs IDs
    44  	err = blockIDs.Parse(rawBlockIDs)
    45  	if err != nil {
    46  		return err
    47  	}
    48  	g.BlockIDs = blockIDs.Flow()
    49  
    50  	// if both height and one or both of start and end height are provided
    51  	if len(blockIDs) > 0 && (g.StartHeight != EmptyHeight || g.EndHeight != EmptyHeight) {
    52  		return fmt.Errorf("can only provide either block IDs or start and end height range")
    53  	}
    54  
    55  	// if neither height nor start and end height are provided
    56  	if len(blockIDs) == 0 && (g.StartHeight == EmptyHeight || g.EndHeight == EmptyHeight) {
    57  		return fmt.Errorf("must provide either block IDs or start and end height range")
    58  	}
    59  
    60  	g.Type = rawType
    61  	if g.Type == "" {
    62  		return fmt.Errorf("event type must be provided")
    63  	}
    64  
    65  	// match basic format A.address.contract.event (ignore err since regex will always compile)
    66  	basic, _ := regexp.MatchString(`[A-Z]\.[a-f0-9]{16}\.[\w+]*\.[\w+]*`, g.Type)
    67  	// match core events flow.event
    68  	core, _ := regexp.MatchString(`flow\.[\w]*`, g.Type)
    69  
    70  	if !core && !basic {
    71  		return fmt.Errorf("invalid event type format")
    72  	}
    73  
    74  	// validate start end height option
    75  	if g.StartHeight != EmptyHeight && g.EndHeight != EmptyHeight {
    76  		if g.StartHeight > g.EndHeight {
    77  			return fmt.Errorf("start height must be less than or equal to end height")
    78  		}
    79  		// check if range exceeds maximum but only if end is not equal to special value which is not known yet
    80  		if g.EndHeight-g.StartHeight >= MaxEventRequestHeightRange && g.EndHeight != FinalHeight && g.EndHeight != SealedHeight {
    81  			return fmt.Errorf("height range %d exceeds maximum allowed of %d", g.EndHeight-g.StartHeight, MaxEventRequestHeightRange)
    82  		}
    83  	}
    84  
    85  	return nil
    86  }