Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions internal/data/statechanges.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ func (m *StateChangeModel) BatchInsert(
ledgerNumbers := make([]int, len(stateChanges))
accountIDBytes := make([][]byte, len(stateChanges))
operationIDs := make([]int64, len(stateChanges))
tokenIDs := make([]*string, len(stateChanges))
tokenIDBytes := make([][]byte, len(stateChanges))
amounts := make([]*string, len(stateChanges))
signerAccountIDBytes := make([][]byte, len(stateChanges))
spenderAccountIDBytes := make([][]byte, len(stateChanges))
Expand Down Expand Up @@ -226,8 +226,9 @@ func (m *StateChangeModel) BatchInsert(
reason := string(*sc.StateChangeReason)
reasons[i] = &reason
}
if sc.TokenID.Valid {
tokenIDs[i] = &sc.TokenID.String
tokenIDBytes[i], err = pgtypeBytesFromNullAddressBytea(sc.TokenID)
if err != nil {
return nil, fmt.Errorf("converting token_id: %w", err)
}
if sc.Amount.Valid {
amounts[i] = &sc.Amount.String
Expand Down Expand Up @@ -305,7 +306,7 @@ func (m *StateChangeModel) BatchInsert(
UNNEST($6::integer[]) AS ledger_number,
UNNEST($7::bytea[]) AS account_id,
UNNEST($8::bigint[]) AS operation_id,
UNNEST($9::text[]) AS token_id,
UNNEST($9::bytea[]) AS token_id,
UNNEST($10::text[]) AS amount,
UNNEST($11::bytea[]) AS signer_account_id,
UNNEST($12::bytea[]) AS spender_account_id,
Expand Down Expand Up @@ -358,7 +359,7 @@ func (m *StateChangeModel) BatchInsert(
pq.Array(ledgerNumbers),
pq.Array(accountIDBytes),
pq.Array(operationIDs),
pq.Array(tokenIDs),
pq.Array(tokenIDBytes),
pq.Array(amounts),
pq.Array(signerAccountIDBytes),
pq.Array(spenderAccountIDBytes),
Expand Down Expand Up @@ -456,6 +457,10 @@ func (m *StateChangeModel) BatchCopy(
if err != nil {
return nil, fmt.Errorf("converting funder_account_id: %w", err)
}
tokenBytes, err := pgtypeBytesFromNullAddressBytea(sc.TokenID)
if err != nil {
return nil, fmt.Errorf("converting token_id: %w", err)
}

return []any{
pgtype.Int8{Int64: sc.ToID, Valid: true},
Expand All @@ -466,7 +471,7 @@ func (m *StateChangeModel) BatchCopy(
pgtype.Int4{Int32: int32(sc.LedgerNumber), Valid: true},
accountBytes,
pgtype.Int8{Int64: sc.OperationID, Valid: true},
pgtypeTextFromNullString(sc.TokenID),
tokenBytes,
pgtypeTextFromNullString(sc.Amount),
signerBytes,
spenderBytes,
Expand Down
8 changes: 4 additions & 4 deletions internal/data/statechanges_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ func generateTestStateChanges(n int, accountID string, startToID int64, auxAddre
LedgerNumber: uint32(i + 1),
AccountID: types.AddressBytea(accountID),
OperationID: int64(i + 1),
// sql.NullString fields
TokenID: sql.NullString{String: fmt.Sprintf("token_%d", i), Valid: true},
// NullAddressBytea token field
TokenID: types.NullAddressBytea{AddressBytea: types.AddressBytea(auxAddresses[(auxIdx+6)%len(auxAddresses)]), Valid: true},
Amount: sql.NullString{String: fmt.Sprintf("%d", (i+1)*100), Valid: true},
// NullAddressBytea fields
SignerAccountID: types.NullAddressBytea{AddressBytea: types.AddressBytea(auxAddresses[auxIdx]), Valid: true},
Expand Down Expand Up @@ -126,7 +126,7 @@ func TestStateChangeModel_BatchInsert(t *testing.T) {
LedgerNumber: 1,
AccountID: types.AddressBytea(kp1.Address()),
OperationID: 123,
TokenID: sql.NullString{String: "token1", Valid: true},
TokenID: types.NullAddressBytea{AddressBytea: types.AddressBytea(kp1.Address()), Valid: true},
Amount: sql.NullString{String: "100", Valid: true},
}
sc2 := types.StateChange{
Expand Down Expand Up @@ -282,7 +282,7 @@ func TestStateChangeModel_BatchCopy(t *testing.T) {
LedgerNumber: 1,
AccountID: types.AddressBytea(kp1.Address()),
OperationID: 123,
TokenID: sql.NullString{String: "token1", Valid: true},
TokenID: types.NullAddressBytea{AddressBytea: types.AddressBytea(kp1.Address()), Valid: true},
Amount: sql.NullString{String: "100", Valid: true},
}
sc2 := types.StateChange{
Expand Down
2 changes: 1 addition & 1 deletion internal/db/migrations/2025-06-10.4-statechanges.sql
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ CREATE TABLE state_changes (
ledger_number INTEGER NOT NULL,
account_id BYTEA NOT NULL,
operation_id BIGINT NOT NULL,
token_id TEXT,
token_id BYTEA,
amount TEXT,
signer_account_id BYTEA,
spender_account_id BYTEA,
Expand Down
2 changes: 1 addition & 1 deletion internal/indexer/indexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ func (i *Indexer) processTransaction(ctx context.Context, tx ingest.LedgerTransa
contractChange := types.ContractChange{
AccountID: string(stateChange.AccountID),
OperationID: stateChange.OperationID,
ContractID: stateChange.TokenID.String,
ContractID: stateChange.TokenID.String(),
LedgerNumber: tx.Ledger.LedgerSequence(),
ContractType: stateChange.ContractType,
}
Expand Down
2 changes: 1 addition & 1 deletion internal/indexer/processors/contracts/test_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -628,7 +628,7 @@ func assertContractEvent(t *testing.T, change types.StateChange, reason types.St
require.Equal(t, expectedAccount, change.AccountID.String())
if expectedContractID != "" {
require.NotNil(t, change.TokenID)
require.Equal(t, expectedContractID, change.TokenID.String)
require.Equal(t, expectedContractID, change.TokenID.String())
}
require.Equal(t, reason, *change.StateChangeReason)
}
Expand Down
6 changes: 3 additions & 3 deletions internal/indexer/processors/effects_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ func TestEffects_ProcessTransaction(t *testing.T) {
asset := xdr.MustNewCreditAsset("TEST", "GBNOOJYISY7Y5IKJFDOGDTVQMPO6DZ46SCS64O2IB4NSCAMXGCKOLORN")
assetContractID, err := asset.ContractID(networkPassphrase)
require.NoError(t, err)
assert.Equal(t, strkey.MustEncode(strkey.VersionByteContract, assetContractID[:]), changes[0].TokenID.String)
assert.Equal(t, strkey.MustEncode(strkey.VersionByteContract, assetContractID[:]), changes[0].TokenID.String())
})
t.Run("ChangeTrust - trustline updated", func(t *testing.T) {
envelopeXDR := "AAAAAHHbEhVipyZ2k4byyCZkS1Bdvpj7faBChuYo8S/Rt89UAAAAZAAQuJIAAAAHAAAAAQAAAAAAAAAAAAAAAF4XVskAAAAAAAAAAQAAAAAAAAAGAAAAAlRFU1RBU1NFVAAAAAAAAAA7JUkkD+tgCi2xTVyEcs4WZXOA0l7w2orZg/bghXOgkAAAAAA7msoAAAAAAAAAAAHRt89UAAAAQOCi2ylqRvvRzZaCFjGkLYFk7DCjJA5uZ1nXo8FaPCRl2LZczoMbc46sZIlHh0ENzk7fKjFnRPMo8XAirrrf2go="
Expand Down Expand Up @@ -413,7 +413,7 @@ func TestEffects_ProcessTransaction(t *testing.T) {
asset := xdr.MustNewCreditAsset("TESTASSET", "GA5SKSJEB7VWACRNWFGVZBDSZYLGK44A2JPPBWUK3GB7NYEFOOQJAC2B")
assetContractID, err := asset.ContractID(networkPassphrase)
require.NoError(t, err)
assert.Equal(t, strkey.MustEncode(strkey.VersionByteContract, assetContractID[:]), changes[0].TokenID.String)
assert.Equal(t, strkey.MustEncode(strkey.VersionByteContract, assetContractID[:]), changes[0].TokenID.String())
assert.Equal(t, "1000000000", changes[0].TrustlineLimitOld.String)
assert.Equal(t, "100.0000000", changes[0].TrustlineLimitNew.String)
})
Expand Down Expand Up @@ -452,6 +452,6 @@ func TestEffects_ProcessTransaction(t *testing.T) {
asset := xdr.MustNewCreditAsset("OCIToken", "GBE4L76HUCHCQ2B7IIWBXRAJDBDPIY6MGWX7VZHUZD2N5RO7XI4J6GTJ")
assetContractID, err := asset.ContractID(networkPassphrase)
require.NoError(t, err)
assert.Equal(t, strkey.MustEncode(strkey.VersionByteContract, assetContractID[:]), changes[0].TokenID.String)
assert.Equal(t, strkey.MustEncode(strkey.VersionByteContract, assetContractID[:]), changes[0].TokenID.String())
})
}
2 changes: 1 addition & 1 deletion internal/indexer/processors/processors_test_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -811,7 +811,7 @@ func assertStateChangeBase(t *testing.T, change types.StateChange, category type
require.Equal(t, utils.SQLNullString(expectedAmount), change.Amount)
}
if expectedToken != "" {
require.Equal(t, utils.SQLNullString(expectedToken), change.TokenID)
require.Equal(t, utils.NullAddressBytea(expectedToken), change.TokenID)
}
}

Expand Down
4 changes: 2 additions & 2 deletions internal/indexer/processors/state_change_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ func (b *StateChangeBuilder) WithAmount(amount string) *StateChangeBuilder {

// WithToken sets the token ID using the contract address
func (b *StateChangeBuilder) WithToken(contractAddress string) *StateChangeBuilder {
b.base.TokenID = utils.SQLNullString(contractAddress)
b.base.TokenID = utils.NullAddressBytea(contractAddress)
return b
}

Expand Down Expand Up @@ -190,7 +190,7 @@ func (b *StateChangeBuilder) generateSortKey() string {
b.base.StateChangeCategory,
reason,
b.base.AccountID,
b.base.TokenID.String,
b.base.TokenID.String(),
b.base.Amount.String,
b.base.SignerAccountID.String(),
b.base.SpenderAccountID.String(),
Expand Down
6 changes: 3 additions & 3 deletions internal/indexer/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -563,9 +563,9 @@ type StateChange struct {
LedgerCreatedAt time.Time `json:"ledgerCreatedAt,omitempty" db:"ledger_created_at"`
LedgerNumber uint32 `json:"ledgerNumber,omitempty" db:"ledger_number"`

// Nullable string fields:
TokenID sql.NullString `json:"tokenId,omitempty" db:"token_id"`
Amount sql.NullString `json:"amount,omitempty" db:"amount"`
// Nullable address fields (stored as BYTEA in database):
TokenID NullAddressBytea `json:"tokenId,omitempty" db:"token_id"`
Amount sql.NullString `json:"amount,omitempty" db:"amount"`

// Nullable address fields (stored as BYTEA in database):
SignerAccountID NullAddressBytea `json:"signerAccountId,omitempty" db:"signer_account_id"`
Expand Down
8 changes: 4 additions & 4 deletions internal/serve/graphql/resolvers/statechange.resolvers.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ func TestStateChangeResolver_NullableStringFields(t *testing.T) {
t.Run("all valid", func(t *testing.T) {
obj := &types.StandardBalanceStateChangeModel{
StateChange: types.StateChange{
TokenID: sql.NullString{String: "token1", Valid: true},
TokenID: types.NullAddressBytea{AddressBytea: types.AddressBytea(MainnetNativeContractAddress), Valid: true},
Amount: sql.NullString{String: "100.5", Valid: true},
},
}

tokenID, err := resolver.TokenID(ctx, obj)
require.NoError(t, err)
assert.Equal(t, "token1", tokenID)
assert.Equal(t, MainnetNativeContractAddress, tokenID)

amount, err := resolver.Amount(ctx, obj)
require.NoError(t, err)
Expand Down
Loading