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

     1  package transform
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/guregu/null/zero"
     7  	"github.com/stellar/go/ingest"
     8  	"github.com/stellar/go/xdr"
     9  	"github.com/stellar/stellar-etl/internal/utils"
    10  )
    11  
    12  // TransformAccount converts an account from the history archive ingestion system into a form suitable for BigQuery
    13  func TransformAccount(ledgerChange ingest.Change, header xdr.LedgerHeaderHistoryEntry) (AccountOutput, error) {
    14  	ledgerEntry, changeType, outputDeleted, err := utils.ExtractEntryFromChange(ledgerChange)
    15  	if err != nil {
    16  		return AccountOutput{}, err
    17  	}
    18  
    19  	accountEntry, accountFound := ledgerEntry.Data.GetAccount()
    20  	if !accountFound {
    21  		return AccountOutput{}, fmt.Errorf("Could not extract account data from ledger entry; actual type is %s", ledgerEntry.Data.Type)
    22  	}
    23  
    24  	outputID, err := accountEntry.AccountId.GetAddress()
    25  	if err != nil {
    26  		return AccountOutput{}, err
    27  	}
    28  
    29  	outputBalance := accountEntry.Balance
    30  	if outputBalance < 0 {
    31  		return AccountOutput{}, fmt.Errorf("Balance is negative (%d) for account: %s", outputBalance, outputID)
    32  	}
    33  
    34  	//The V1 struct is the first version of the extender from accountEntry. It contains information on liabilities, and in the future
    35  	//more extensions may contain extra information
    36  	accountExtensionInfo, V1Found := accountEntry.Ext.GetV1()
    37  	var outputBuyingLiabilities, outputSellingLiabilities xdr.Int64
    38  	if V1Found {
    39  		liabilities := accountExtensionInfo.Liabilities
    40  		outputBuyingLiabilities, outputSellingLiabilities = liabilities.Buying, liabilities.Selling
    41  		if outputBuyingLiabilities < 0 {
    42  			return AccountOutput{}, fmt.Errorf("The buying liabilities count is negative (%d) for account: %s", outputBuyingLiabilities, outputID)
    43  		}
    44  
    45  		if outputSellingLiabilities < 0 {
    46  			return AccountOutput{}, fmt.Errorf("The selling liabilities count is negative (%d) for account: %s", outputSellingLiabilities, outputID)
    47  		}
    48  	}
    49  
    50  	outputSequenceNumber := int64(accountEntry.SeqNum)
    51  	if outputSequenceNumber < 0 {
    52  		return AccountOutput{}, fmt.Errorf("Account sequence number is negative (%d) for account: %s", outputSequenceNumber, outputID)
    53  	}
    54  	outputSequenceLedger := accountEntry.SeqLedger()
    55  	outputSequenceTime := accountEntry.SeqTime()
    56  
    57  	outputNumSubentries := uint32(accountEntry.NumSubEntries)
    58  
    59  	inflationDestAccountID := accountEntry.InflationDest
    60  	var outputInflationDest string
    61  	if inflationDestAccountID != nil {
    62  		outputInflationDest, err = inflationDestAccountID.GetAddress()
    63  		if err != nil {
    64  			return AccountOutput{}, err
    65  		}
    66  	}
    67  
    68  	outputFlags := uint32(accountEntry.Flags)
    69  
    70  	outputHomeDomain := string(accountEntry.HomeDomain)
    71  
    72  	outputMasterWeight := int32(accountEntry.MasterKeyWeight())
    73  	outputThreshLow := int32(accountEntry.ThresholdLow())
    74  	outputThreshMed := int32(accountEntry.ThresholdMedium())
    75  	outputThreshHigh := int32(accountEntry.ThresholdHigh())
    76  
    77  	outputLastModifiedLedger := uint32(ledgerEntry.LastModifiedLedgerSeq)
    78  
    79  	closedAt, err := utils.TimePointToUTCTimeStamp(header.Header.ScpValue.CloseTime)
    80  	if err != nil {
    81  		return AccountOutput{}, err
    82  	}
    83  
    84  	ledgerSequence := header.Header.LedgerSeq
    85  
    86  	transformedAccount := AccountOutput{
    87  		AccountID:            outputID,
    88  		Balance:              utils.ConvertStroopValueToReal(outputBalance),
    89  		BuyingLiabilities:    utils.ConvertStroopValueToReal(outputBuyingLiabilities),
    90  		SellingLiabilities:   utils.ConvertStroopValueToReal(outputSellingLiabilities),
    91  		SequenceNumber:       outputSequenceNumber,
    92  		SequenceLedger:       zero.IntFrom(int64(outputSequenceLedger)),
    93  		SequenceTime:         zero.IntFrom(int64(outputSequenceTime)),
    94  		NumSubentries:        outputNumSubentries,
    95  		InflationDestination: outputInflationDest,
    96  		Flags:                outputFlags,
    97  		HomeDomain:           outputHomeDomain,
    98  		MasterWeight:         outputMasterWeight,
    99  		ThresholdLow:         outputThreshLow,
   100  		ThresholdMedium:      outputThreshMed,
   101  		ThresholdHigh:        outputThreshHigh,
   102  		LastModifiedLedger:   outputLastModifiedLedger,
   103  		Sponsor:              ledgerEntrySponsorToNullString(ledgerEntry),
   104  		NumSponsored:         uint32(accountEntry.NumSponsored()),
   105  		NumSponsoring:        uint32(accountEntry.NumSponsoring()),
   106  		LedgerEntryChange:    uint32(changeType),
   107  		Deleted:              outputDeleted,
   108  		ClosedAt:             closedAt,
   109  		LedgerSequence:       uint32(ledgerSequence),
   110  	}
   111  	return transformedAccount, nil
   112  }