github.com/koko1123/flow-go-1@v0.29.6/admin/commands/storage/read_transactions.go (about)

     1  package storage
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/rs/zerolog/log"
     7  
     8  	"github.com/koko1123/flow-go-1/admin"
     9  	"github.com/koko1123/flow-go-1/admin/commands"
    10  	"github.com/koko1123/flow-go-1/cmd/util/cmd/export-json-transactions/transactions"
    11  	"github.com/koko1123/flow-go-1/state/protocol"
    12  	"github.com/koko1123/flow-go-1/storage"
    13  )
    14  
    15  var _ commands.AdminCommand = (*GetTransactionsCommand)(nil)
    16  
    17  // max number of block height to query transactions from
    18  var MAX_HEIGHT_RANGE = uint64(1000)
    19  
    20  type getTransactionsReqData struct {
    21  	startHeight uint64
    22  	endHeight   uint64
    23  }
    24  
    25  type GetTransactionsCommand struct {
    26  	state       protocol.State
    27  	payloads    storage.Payloads
    28  	collections storage.Collections
    29  }
    30  
    31  func NewGetTransactionsCommand(state protocol.State, payloads storage.Payloads, collections storage.Collections) *GetTransactionsCommand {
    32  	return &GetTransactionsCommand{
    33  		state:       state,
    34  		payloads:    payloads,
    35  		collections: collections,
    36  	}
    37  }
    38  
    39  func (c *GetTransactionsCommand) Handler(ctx context.Context, req *admin.CommandRequest) (interface{}, error) {
    40  	data := req.ValidatorData.(*getTransactionsReqData)
    41  
    42  	finder := &transactions.Finder{
    43  		State:       c.state,
    44  		Payloads:    c.payloads,
    45  		Collections: c.collections,
    46  	}
    47  
    48  	log.Info().Str("module", "admin-tool").Msgf("get transactions for height range [%v, %v]",
    49  		data.startHeight, data.endHeight)
    50  	blocks, err := finder.GetByHeightRange(data.startHeight, data.endHeight)
    51  	if err != nil {
    52  		return nil, err
    53  	}
    54  
    55  	return commands.ConvertToInterfaceList(blocks)
    56  }
    57  
    58  // Returns admin.InvalidAdminReqError for invalid inputs
    59  func findUint64(input map[string]interface{}, field string) (uint64, error) {
    60  	data, ok := input[field]
    61  	if !ok {
    62  		return 0, admin.NewInvalidAdminReqErrorf("missing required field '%s'", field)
    63  	}
    64  	val, err := parseN(data)
    65  	if err != nil {
    66  		return 0, admin.NewInvalidAdminReqErrorf("invalid 'n' field: %w", err)
    67  	}
    68  
    69  	return uint64(val), nil
    70  }
    71  
    72  // Validator validates the request.
    73  // Returns admin.InvalidAdminReqError for invalid/malformed requests.
    74  func (c *GetTransactionsCommand) Validator(req *admin.CommandRequest) error {
    75  	input, ok := req.Data.(map[string]interface{})
    76  	if !ok {
    77  		return admin.NewInvalidAdminReqFormatError("expected map[string]any")
    78  	}
    79  
    80  	startHeight, err := findUint64(input, "start-height")
    81  	if err != nil {
    82  		return err
    83  	}
    84  
    85  	endHeight, err := findUint64(input, "end-height")
    86  	if err != nil {
    87  		return err
    88  	}
    89  
    90  	if endHeight < startHeight {
    91  		return admin.NewInvalidAdminReqErrorf("endHeight %v should not be smaller than startHeight %v", endHeight, startHeight)
    92  	}
    93  
    94  	if endHeight-startHeight+1 > MAX_HEIGHT_RANGE {
    95  		return admin.NewInvalidAdminReqErrorf("getting transactions for more than %v blocks at a time might have an impact to node's performance and is not allowed", MAX_HEIGHT_RANGE)
    96  	}
    97  
    98  	req.ValidatorData = &getTransactionsReqData{
    99  		startHeight: startHeight,
   100  		endHeight:   endHeight,
   101  	}
   102  
   103  	return nil
   104  }