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
50 changes: 0 additions & 50 deletions docs/swagger/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8369,16 +8369,6 @@ paths:
schema:
default: 120s
type: string
- description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
in: query
name: balance
schema:
type: string
- description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
in: query
name: connector
schema:
type: string
- description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
in: query
name: key
Expand All @@ -8389,26 +8379,11 @@ paths:
name: namespace
schema:
type: string
- description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
in: query
name: pool
schema:
type: string
- description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
in: query
name: tokenindex
schema:
type: string
- description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
in: query
name: updated
schema:
type: string
- description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
in: query
name: uri
schema:
type: string
- description: Sort field. For multi-field sort use comma separated values (or
multiple query values) with '-' prefix for descending
in: query
Expand Down Expand Up @@ -8480,21 +8455,6 @@ paths:
schema:
default: 120s
type: string
- description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
in: query
name: balance
schema:
type: string
- description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
in: query
name: connector
schema:
type: string
- description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
in: query
name: key
schema:
type: string
- description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
in: query
name: namespace
Expand All @@ -8505,21 +8465,11 @@ paths:
name: pool
schema:
type: string
- description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
in: query
name: tokenindex
schema:
type: string
- description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
in: query
name: updated
schema:
type: string
- description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
in: query
name: uri
schema:
type: string
- description: Sort field. For multi-field sort use comma separated values (or
multiple query values) with '-' prefix for descending
in: query
Expand Down
2 changes: 1 addition & 1 deletion internal/apiserver/route_get_token_account_pools.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ var getTokenAccountPools = &oapispec.Route{
{Name: "key", Description: i18n.MsgTBD},
},
QueryParams: nil,
FilterFactory: database.TokenBalanceQueryFactory,
FilterFactory: database.TokenAccountPoolQueryFactory,
Description: i18n.MsgTBD,
JSONInputValue: nil,
JSONOutputValue: func() interface{} { return []*fftypes.TokenAccountPool{} },
Expand Down
2 changes: 1 addition & 1 deletion internal/apiserver/route_get_token_accounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ var getTokenAccounts = &oapispec.Route{
{Name: "ns", ExampleFromConf: config.NamespacesDefault, Description: i18n.MsgTBD},
},
QueryParams: nil,
FilterFactory: database.TokenBalanceQueryFactory,
FilterFactory: database.TokenAccountQueryFactory,
Description: i18n.MsgTBD,
JSONInputValue: nil,
JSONOutputValue: func() interface{} { return []*fftypes.TokenAccount{} },
Expand Down
16 changes: 9 additions & 7 deletions internal/database/sqlcommon/tokenbalance_sql.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright © 2021 Kaleido, Inc.
// Copyright © 2022 Kaleido, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
Expand Down Expand Up @@ -198,12 +198,11 @@ func (s *SQLCommon) GetTokenBalances(ctx context.Context, filter database.Filter

func (s *SQLCommon) GetTokenAccounts(ctx context.Context, filter database.Filter) ([]*fftypes.TokenAccount, *database.FilterResult, error) {
query, fop, fi, err := s.filterSelect(ctx, "",
sq.Select("key").Distinct().From("tokenbalance"),
sq.Select("key", "MAX(updated) AS updated", "MAX(seq) AS seq").From("tokenbalance").GroupBy("key"),
filter, tokenBalanceFilterFieldMap, []interface{}{"seq"})
if err != nil {
return nil, nil, err
}
fi.CountExpr = "DISTINCT key"

rows, tx, err := s.query(ctx, query)
if err != nil {
Expand All @@ -214,7 +213,9 @@ func (s *SQLCommon) GetTokenAccounts(ctx context.Context, filter database.Filter
accounts := make([]*fftypes.TokenAccount, 0)
for rows.Next() {
var account fftypes.TokenAccount
if err := rows.Scan(&account.Key); err != nil {
var updated fftypes.FFTime
var seq int64
if err := rows.Scan(&account.Key, &updated, &seq); err != nil {
return nil, nil, i18n.WrapError(ctx, err, i18n.MsgDBReadErr, "tokenbalance")
}
accounts = append(accounts, &account)
Expand All @@ -225,13 +226,12 @@ func (s *SQLCommon) GetTokenAccounts(ctx context.Context, filter database.Filter

func (s *SQLCommon) GetTokenAccountPools(ctx context.Context, key string, filter database.Filter) ([]*fftypes.TokenAccountPool, *database.FilterResult, error) {
query, fop, fi, err := s.filterSelect(ctx, "",
sq.Select("pool_id").Distinct().From("tokenbalance"),
sq.Select("pool_id", "MAX(updated) AS updated", "MAX(seq) AS seq").From("tokenbalance").GroupBy("pool_id"),
filter, tokenBalanceFilterFieldMap, []interface{}{"seq"},
sq.Eq{"key": key})
if err != nil {
return nil, nil, err
}
fi.CountExpr = "DISTINCT pool_id"

rows, tx, err := s.query(ctx, query)
if err != nil {
Expand All @@ -242,7 +242,9 @@ func (s *SQLCommon) GetTokenAccountPools(ctx context.Context, key string, filter
pools := make([]*fftypes.TokenAccountPool, 0)
for rows.Next() {
var pool fftypes.TokenAccountPool
if err := rows.Scan(&pool.Pool); err != nil {
var updated fftypes.FFTime
var seq int64
if err := rows.Scan(&pool.Pool, &updated, &seq); err != nil {
return nil, nil, i18n.WrapError(ctx, err, i18n.MsgDBReadErr, "tokenbalance")
}
pools = append(pools, &pool)
Expand Down
16 changes: 15 additions & 1 deletion pkg/database/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -860,7 +860,7 @@ var TokenPoolQueryFactory = &queryFields{
"connector": &StringField{},
}

// TokenBalanceQueryFactory filter fields for token accounts
// TokenBalanceQueryFactory filter fields for token balances
var TokenBalanceQueryFactory = &queryFields{
"pool": &UUIDField{},
"tokenindex": &StringField{},
Expand All @@ -872,6 +872,20 @@ var TokenBalanceQueryFactory = &queryFields{
"updated": &TimeField{},
}

// TokenAccountQueryFactory filter fields for token accounts
var TokenAccountQueryFactory = &queryFields{
"key": &StringField{},
"namespace": &StringField{},
"updated": &TimeField{},
}

// TokenAccountPoolQueryFactory filter fields for token account pools
var TokenAccountPoolQueryFactory = &queryFields{
"pool": &UUIDField{},
"namespace": &StringField{},
"updated": &TimeField{},
}

// TokenTransferQueryFactory filter fields for token transfers
var TokenTransferQueryFactory = &queryFields{
"localid": &StringField{},
Expand Down
22 changes: 22 additions & 0 deletions test/e2e/restclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ var (
urlTokenMint = "/namespaces/default/tokens/mint"
urlTokenBurn = "/namespaces/default/tokens/burn"
urlTokenTransfers = "/namespaces/default/tokens/transfers"
urlTokenAccounts = "/namespaces/default/tokens/accounts"
urlTokenBalances = "/namespaces/default/tokens/balances"
urlContractInvoke = "/namespaces/default/contracts/invoke"
urlContractQuery = "/namespaces/default/contracts/query"
Expand Down Expand Up @@ -439,6 +440,27 @@ func GetTokenTransfers(t *testing.T, client *resty.Client, poolID *fftypes.UUID)
return transfers
}

func GetTokenAccounts(t *testing.T, client *resty.Client, poolID *fftypes.UUID) (accounts []*fftypes.TokenAccount) {
path := urlTokenAccounts
resp, err := client.R().
SetResult(&accounts).
Get(path)
require.NoError(t, err)
require.Equal(t, 200, resp.StatusCode(), "GET %s [%d]: %s", path, resp.StatusCode(), resp.String())
return accounts
}

func GetTokenAccountPools(t *testing.T, client *resty.Client, identity string) (pools []*fftypes.TokenAccountPool) {
path := urlTokenAccounts + "/" + identity + "/pools"
resp, err := client.R().
SetQueryParam("sort", "-updated").
SetResult(&pools).
Get(path)
require.NoError(t, err)
require.Equal(t, 200, resp.StatusCode(), "GET %s [%d]: %s", path, resp.StatusCode(), resp.String())
return pools
}

func GetTokenBalance(t *testing.T, client *resty.Client, poolID *fftypes.UUID, tokenIndex, key string) (account *fftypes.TokenBalance) {
var accounts []*fftypes.TokenBalance
path := urlTokenBalances
Expand Down
28 changes: 28 additions & 0 deletions test/e2e/tokens_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,20 @@ func (suite *TokensTestSuite) TestE2EFungibleTokensAsync() {
suite.testState.org1.Identity: 0,
suite.testState.org2.Identity: 0,
})

accounts := GetTokenAccounts(suite.T(), suite.testState.client1, poolID)
assert.Equal(suite.T(), 2, len(accounts))
assert.Equal(suite.T(), suite.testState.org2.Identity, accounts[0].Key)
assert.Equal(suite.T(), suite.testState.org1.Identity, accounts[1].Key)
accounts = GetTokenAccounts(suite.T(), suite.testState.client2, poolID)
assert.Equal(suite.T(), 2, len(accounts))
assert.Equal(suite.T(), suite.testState.org2.Identity, accounts[0].Key)
assert.Equal(suite.T(), suite.testState.org1.Identity, accounts[1].Key)

accountPools := GetTokenAccountPools(suite.T(), suite.testState.client1, suite.testState.org1.Identity)
assert.Equal(suite.T(), *poolID, *accountPools[0].Pool)
accountPools = GetTokenAccountPools(suite.T(), suite.testState.client2, suite.testState.org2.Identity)
assert.Equal(suite.T(), *poolID, *accountPools[0].Pool)
}

func (suite *TokensTestSuite) TestE2ENonFungibleTokensSync() {
Expand Down Expand Up @@ -287,4 +301,18 @@ func (suite *TokensTestSuite) TestE2ENonFungibleTokensSync() {
suite.testState.org1.Identity: 0,
suite.testState.org2.Identity: 0,
})

accounts := GetTokenAccounts(suite.T(), suite.testState.client1, poolID)
assert.Equal(suite.T(), 2, len(accounts))
assert.Equal(suite.T(), suite.testState.org2.Identity, accounts[0].Key)
assert.Equal(suite.T(), suite.testState.org1.Identity, accounts[1].Key)
accounts = GetTokenAccounts(suite.T(), suite.testState.client2, poolID)
assert.Equal(suite.T(), 2, len(accounts))
assert.Equal(suite.T(), suite.testState.org2.Identity, accounts[0].Key)
assert.Equal(suite.T(), suite.testState.org1.Identity, accounts[1].Key)

accountPools := GetTokenAccountPools(suite.T(), suite.testState.client1, suite.testState.org1.Identity)
assert.Equal(suite.T(), *poolID, *accountPools[0].Pool)
accountPools = GetTokenAccountPools(suite.T(), suite.testState.client2, suite.testState.org2.Identity)
assert.Equal(suite.T(), *poolID, *accountPools[0].Pool)
}