github.com/stellar/stellar-etl@v1.0.1-0.20240312145900-4874b6bf2b89/internal/input/operations.go (about)

     1  package input
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"io"
     7  
     8  	"github.com/stellar/go/ingest"
     9  	"github.com/stellar/go/ingest/ledgerbackend"
    10  	"github.com/stellar/go/xdr"
    11  	"github.com/stellar/stellar-etl/internal/utils"
    12  )
    13  
    14  // OperationTransformInput is a representation of the input for the TransformOperation function
    15  type OperationTransformInput struct {
    16  	Operation       xdr.Operation
    17  	OperationIndex  int32
    18  	Transaction     ingest.LedgerTransaction
    19  	LedgerSeqNum    int32
    20  	LedgerCloseMeta xdr.LedgerCloseMeta
    21  }
    22  
    23  func panicIf(err error) {
    24  	if err != nil {
    25  		panic(fmt.Errorf("An error occurred, panicking: %s\n", err))
    26  	}
    27  }
    28  
    29  // GetOperations returns a slice of operations for the ledgers in the provided range (inclusive on both ends)
    30  func GetOperations(start, end uint32, limit int64, env utils.EnvironmentDetails) ([]OperationTransformInput, error) {
    31  	ctx := context.Background()
    32  
    33  	backend, err := env.CreateCaptiveCoreBackend()
    34  
    35  	if err != nil {
    36  		return []OperationTransformInput{}, err
    37  	}
    38  
    39  	opSlice := []OperationTransformInput{}
    40  	err = backend.PrepareRange(ctx, ledgerbackend.BoundedRange(start, end))
    41  	panicIf(err)
    42  	for seq := start; seq <= end; seq++ {
    43  		changeReader, err := ingest.NewLedgerChangeReader(ctx, backend, env.NetworkPassphrase, seq)
    44  		if err != nil {
    45  			return []OperationTransformInput{}, err
    46  		}
    47  		txReader := changeReader.LedgerTransactionReader
    48  
    49  		ledgerCloseMeta, err := backend.GetLedger(ctx, seq)
    50  		if err != nil {
    51  			return nil, fmt.Errorf("error getting ledger seq %d from the backend: %v", seq, err)
    52  		}
    53  
    54  		for int64(len(opSlice)) < limit || limit < 0 {
    55  			tx, err := txReader.Read()
    56  			if err == io.EOF {
    57  				break
    58  			}
    59  
    60  			for index, op := range tx.Envelope.Operations() {
    61  				opSlice = append(opSlice, OperationTransformInput{
    62  					Operation:       op,
    63  					OperationIndex:  int32(index),
    64  					Transaction:     tx,
    65  					LedgerSeqNum:    int32(seq),
    66  					LedgerCloseMeta: ledgerCloseMeta,
    67  				})
    68  
    69  				if int64(len(opSlice)) >= limit && limit >= 0 {
    70  					break
    71  				}
    72  			}
    73  		}
    74  
    75  		txReader.Close()
    76  		if int64(len(opSlice)) >= limit && limit >= 0 {
    77  			break
    78  		}
    79  	}
    80  
    81  	return opSlice, nil
    82  }