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

     1  package transform
     2  
     3  import (
     4  	"encoding/base64"
     5  	"fmt"
     6  
     7  	"github.com/guregu/null"
     8  	"github.com/pkg/errors"
     9  
    10  	"github.com/stellar/stellar-etl/internal/utils"
    11  
    12  	"github.com/stellar/go/ingest"
    13  	"github.com/stellar/go/xdr"
    14  )
    15  
    16  // TransformTrustline converts a trustline from the history archive ingestion system into a form suitable for BigQuery
    17  func TransformTrustline(ledgerChange ingest.Change, header xdr.LedgerHeaderHistoryEntry) (TrustlineOutput, error) {
    18  	ledgerEntry, changeType, outputDeleted, err := utils.ExtractEntryFromChange(ledgerChange)
    19  	if err != nil {
    20  		return TrustlineOutput{}, err
    21  	}
    22  
    23  	trustEntry, ok := ledgerEntry.Data.GetTrustLine()
    24  	if !ok {
    25  		return TrustlineOutput{}, fmt.Errorf("Could not extract trustline data from ledger entry; actual type is %s", ledgerEntry.Data.Type)
    26  	}
    27  
    28  	outputAccountID, err := trustEntry.AccountId.GetAddress()
    29  	if err != nil {
    30  		return TrustlineOutput{}, err
    31  	}
    32  
    33  	var assetType, outputAssetCode, outputAssetIssuer, poolID string
    34  
    35  	asset := trustEntry.Asset
    36  
    37  	outputLedgerKey, err := trustLineEntryToLedgerKeyString(trustEntry)
    38  	if err != nil {
    39  		return TrustlineOutput{}, errors.Wrap(err, fmt.Sprintf("could not create ledger key string for trustline with account %s and asset %s", outputAccountID, asset.ToAsset().StringCanonical()))
    40  	}
    41  
    42  	if asset.Type == xdr.AssetTypeAssetTypePoolShare {
    43  		poolID = PoolIDToString(trustEntry.Asset.MustLiquidityPoolId())
    44  	} else {
    45  		if err = asset.Extract(&assetType, &outputAssetCode, &outputAssetIssuer); err != nil {
    46  			return TrustlineOutput{}, errors.Wrap(err, fmt.Sprintf("could not parse asset for trustline with account %s", outputAccountID))
    47  		}
    48  	}
    49  
    50  	outputAssetID := FarmHashAsset(outputAssetCode, outputAssetIssuer, asset.Type.String())
    51  
    52  	liabilities := trustEntry.Liabilities()
    53  
    54  	closedAt, err := utils.TimePointToUTCTimeStamp(header.Header.ScpValue.CloseTime)
    55  	if err != nil {
    56  		return TrustlineOutput{}, err
    57  	}
    58  
    59  	ledgerSequence := header.Header.LedgerSeq
    60  
    61  	transformedTrustline := TrustlineOutput{
    62  		LedgerKey:          outputLedgerKey,
    63  		AccountID:          outputAccountID,
    64  		AssetType:          int32(asset.Type),
    65  		AssetCode:          outputAssetCode,
    66  		AssetIssuer:        outputAssetIssuer,
    67  		AssetID:            outputAssetID,
    68  		Balance:            utils.ConvertStroopValueToReal(trustEntry.Balance),
    69  		TrustlineLimit:     int64(trustEntry.Limit),
    70  		LiquidityPoolID:    poolID,
    71  		BuyingLiabilities:  utils.ConvertStroopValueToReal(liabilities.Buying),
    72  		SellingLiabilities: utils.ConvertStroopValueToReal(liabilities.Selling),
    73  		Flags:              uint32(trustEntry.Flags),
    74  		LastModifiedLedger: uint32(ledgerEntry.LastModifiedLedgerSeq),
    75  		LedgerEntryChange:  uint32(changeType),
    76  		Sponsor:            ledgerEntrySponsorToNullString(ledgerEntry),
    77  		Deleted:            outputDeleted,
    78  		ClosedAt:           closedAt,
    79  		LedgerSequence:     uint32(ledgerSequence),
    80  	}
    81  
    82  	return transformedTrustline, nil
    83  }
    84  
    85  func trustLineEntryToLedgerKeyString(trustLine xdr.TrustLineEntry) (string, error) {
    86  	ledgerKey := &xdr.LedgerKey{}
    87  	err := ledgerKey.SetTrustline(trustLine.AccountId, trustLine.Asset)
    88  	if err != nil {
    89  		return "", fmt.Errorf("Error running ledgerKey.SetTrustline when calculating ledger key")
    90  	}
    91  
    92  	key, err := ledgerKey.MarshalBinary()
    93  	if err != nil {
    94  		return "", fmt.Errorf("Error running MarshalBinaryCompress when calculating ledger key")
    95  	}
    96  
    97  	return base64.StdEncoding.EncodeToString(key), nil
    98  
    99  }
   100  
   101  func ledgerEntrySponsorToNullString(entry xdr.LedgerEntry) null.String {
   102  	sponsoringID := entry.SponsoringID()
   103  
   104  	var sponsor null.String
   105  	if sponsoringID != nil {
   106  		sponsor.SetValid((*sponsoringID).Address())
   107  	}
   108  
   109  	return sponsor
   110  }