From cf0b07eebcf4e5587a02aee2d9e9b4b8b5aa7ece Mon Sep 17 00:00:00 2001 From: Andrew Richardson Date: Tue, 19 Oct 2021 15:15:00 -0400 Subject: [PATCH 1/4] Add "connector" field to token accounts and transfers Signed-off-by: Andrew Richardson --- ...000033_add_token_connector_fields.down.sql | 4 + .../000033_add_token_connector_fields.up.sql | 17 ++++ ...000033_add_token_connector_fields.down.sql | 2 + .../000033_add_token_connector_fields.up.sql | 11 +++ docs/swagger/swagger.yaml | 46 +++++++++++ internal/apiserver/route_post_token_burn.go | 2 +- internal/apiserver/route_post_token_mint.go | 2 +- .../apiserver/route_post_token_transfer.go | 2 +- internal/assets/manager.go | 22 +++--- internal/assets/token_pool.go | 24 +++--- internal/assets/token_transfer.go | 27 +++---- internal/assets/token_transfer_test.go | 2 +- .../database/sqlcommon/tokenaccount_sql.go | 3 + .../sqlcommon/tokenaccount_sql_test.go | 5 +- .../database/sqlcommon/tokentransfer_sql.go | 4 + .../sqlcommon/tokentransfer_sql_test.go | 1 + internal/events/tokens_transferred.go | 1 + internal/tokens/fftokens/config.go | 2 +- internal/tokens/fftokens/fftokens.go | 78 ++++++++++--------- pkg/database/plugin.go | 2 + pkg/fftypes/tokenaccount.go | 2 + pkg/fftypes/tokentransfer.go | 1 + test/e2e/e2e_test.go | 9 +++ 23 files changed, 190 insertions(+), 79 deletions(-) create mode 100644 db/migrations/postgres/000033_add_token_connector_fields.down.sql create mode 100644 db/migrations/postgres/000033_add_token_connector_fields.up.sql create mode 100644 db/migrations/sqlite/000033_add_token_connector_fields.down.sql create mode 100644 db/migrations/sqlite/000033_add_token_connector_fields.up.sql diff --git a/db/migrations/postgres/000033_add_token_connector_fields.down.sql b/db/migrations/postgres/000033_add_token_connector_fields.down.sql new file mode 100644 index 0000000000..5401621393 --- /dev/null +++ b/db/migrations/postgres/000033_add_token_connector_fields.down.sql @@ -0,0 +1,4 @@ +BEGIN; +ALTER TABLE tokenaccount DROP COLUMN connector; +ALTER TABLE tokentransfer DROP COLUMN connector; +COMMIT; diff --git a/db/migrations/postgres/000033_add_token_connector_fields.up.sql b/db/migrations/postgres/000033_add_token_connector_fields.up.sql new file mode 100644 index 0000000000..cb2854fc70 --- /dev/null +++ b/db/migrations/postgres/000033_add_token_connector_fields.up.sql @@ -0,0 +1,17 @@ +BEGIN; + +ALTER TABLE tokenaccount ADD COLUMN connector VARCHAR(64); +ALTER TABLE tokentransfer ADD COLUMN connector VARCHAR(64); + +UPDATE tokenaccount SET connector = pool.connector + FROM (SELECT protocol_id, connector FROM tokenpool) AS pool + WHERE tokenaccount.pool_protocol_id = pool.protocol_id; + +UPDATE tokentransfer SET connector = pool.connector + FROM (SELECT protocol_id, connector FROM tokenpool) AS pool + WHERE tokentransfer.pool_protocol_id = pool.protocol_id; + +ALTER TABLE tokenaccount ALTER COLUMN connector SET NOT NULL; +ALTER TABLE tokentransfer ALTER COLUMN connector SET NOT NULL; + +COMMIT; diff --git a/db/migrations/sqlite/000033_add_token_connector_fields.down.sql b/db/migrations/sqlite/000033_add_token_connector_fields.down.sql new file mode 100644 index 0000000000..ec7b622f31 --- /dev/null +++ b/db/migrations/sqlite/000033_add_token_connector_fields.down.sql @@ -0,0 +1,2 @@ +ALTER TABLE tokenaccount DROP COLUMN connector; +ALTER TABLE tokentransfer DROP COLUMN connector; diff --git a/db/migrations/sqlite/000033_add_token_connector_fields.up.sql b/db/migrations/sqlite/000033_add_token_connector_fields.up.sql new file mode 100644 index 0000000000..c2b5349af0 --- /dev/null +++ b/db/migrations/sqlite/000033_add_token_connector_fields.up.sql @@ -0,0 +1,11 @@ +DELETE FROM tokenaccount; +ALTER TABLE tokenaccount ADD COLUMN connector VARCHAR(64); +ALTER TABLE tokentransfer ADD COLUMN connector VARCHAR(64); + +UPDATE tokenaccount SET connector = pool.connector + FROM (SELECT protocol_id, connector FROM tokenpool) AS pool + WHERE tokenaccount.pool_protocol_id = pool.protocol_id; + +UPDATE tokentransfer SET connector = pool.connector + FROM (SELECT protocol_id, connector FROM tokenpool) AS pool + WHERE tokentransfer.pool_protocol_id = pool.protocol_id; diff --git a/docs/swagger/swagger.yaml b/docs/swagger/swagger.yaml index 8b44d824ff..aecb499cff 100644 --- a/docs/swagger/swagger.yaml +++ b/docs/swagger/swagger.yaml @@ -4633,6 +4633,11 @@ paths: 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: identity @@ -4690,6 +4695,8 @@ paths: items: properties: balance: {} + connector: + type: string identity: type: string poolProtocolId: @@ -4743,6 +4750,8 @@ paths: schema: properties: amount: {} + connector: + type: string created: {} from: type: string @@ -4865,6 +4874,8 @@ paths: schema: properties: amount: {} + connector: + type: string created: {} from: type: string @@ -4896,6 +4907,8 @@ paths: schema: properties: amount: {} + connector: + type: string created: {} from: type: string @@ -4965,6 +4978,8 @@ paths: schema: properties: amount: {} + connector: + type: string created: {} from: type: string @@ -5087,6 +5102,8 @@ paths: schema: properties: amount: {} + connector: + type: string created: {} from: type: string @@ -5118,6 +5135,8 @@ paths: schema: properties: amount: {} + connector: + type: string created: {} from: type: string @@ -5181,6 +5200,11 @@ paths: name: amount 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: created @@ -5268,6 +5292,8 @@ paths: items: properties: amount: {} + connector: + type: string created: {} from: type: string @@ -5337,6 +5363,8 @@ paths: schema: properties: amount: {} + connector: + type: string created: {} from: type: string @@ -5459,6 +5487,8 @@ paths: schema: properties: amount: {} + connector: + type: string created: {} from: type: string @@ -5490,6 +5520,8 @@ paths: schema: properties: amount: {} + connector: + type: string created: {} from: type: string @@ -5541,6 +5573,11 @@ paths: 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: identity @@ -5598,6 +5635,8 @@ paths: items: properties: balance: {} + connector: + type: string identity: type: string poolProtocolId: @@ -5802,6 +5841,11 @@ paths: name: amount 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: created @@ -5889,6 +5933,8 @@ paths: items: properties: amount: {} + connector: + type: string created: {} from: type: string diff --git a/internal/apiserver/route_post_token_burn.go b/internal/apiserver/route_post_token_burn.go index 35e579b55f..232e080f52 100644 --- a/internal/apiserver/route_post_token_burn.go +++ b/internal/apiserver/route_post_token_burn.go @@ -41,7 +41,7 @@ var postTokenBurn = &oapispec.Route{ FilterFactory: nil, Description: i18n.MsgTBD, JSONInputValue: func() interface{} { return &fftypes.TokenTransferInput{} }, - JSONInputMask: []string{"Type", "LocalID", "PoolProtocolID", "To", "ProtocolID", "MessageHash", "TX", "Created"}, + JSONInputMask: []string{"Type", "LocalID", "PoolProtocolID", "To", "ProtocolID", "MessageHash", "Connector", "TX", "Created"}, JSONOutputValue: func() interface{} { return &fftypes.TokenTransfer{} }, JSONOutputCodes: []int{http.StatusAccepted, http.StatusOK}, JSONHandler: func(r *oapispec.APIRequest) (output interface{}, err error) { diff --git a/internal/apiserver/route_post_token_mint.go b/internal/apiserver/route_post_token_mint.go index b134aef51f..608f12d7a9 100644 --- a/internal/apiserver/route_post_token_mint.go +++ b/internal/apiserver/route_post_token_mint.go @@ -41,7 +41,7 @@ var postTokenMint = &oapispec.Route{ FilterFactory: nil, Description: i18n.MsgTBD, JSONInputValue: func() interface{} { return &fftypes.TokenTransferInput{} }, - JSONInputMask: []string{"Type", "LocalID", "PoolProtocolID", "TokenIndex", "From", "ProtocolID", "MessageHash", "TX", "Created"}, + JSONInputMask: []string{"Type", "LocalID", "PoolProtocolID", "TokenIndex", "From", "ProtocolID", "MessageHash", "Connector", "TX", "Created"}, JSONOutputValue: func() interface{} { return &fftypes.TokenTransfer{} }, JSONOutputCodes: []int{http.StatusAccepted, http.StatusOK}, JSONHandler: func(r *oapispec.APIRequest) (output interface{}, err error) { diff --git a/internal/apiserver/route_post_token_transfer.go b/internal/apiserver/route_post_token_transfer.go index 970f7ec38f..c36ef24542 100644 --- a/internal/apiserver/route_post_token_transfer.go +++ b/internal/apiserver/route_post_token_transfer.go @@ -41,7 +41,7 @@ var postTokenTransfer = &oapispec.Route{ FilterFactory: nil, Description: i18n.MsgTBD, JSONInputValue: func() interface{} { return &fftypes.TokenTransferInput{} }, - JSONInputMask: []string{"Type", "LocalID", "PoolProtocolID", "ProtocolID", "MessageHash", "TX", "Created"}, + JSONInputMask: []string{"Type", "LocalID", "PoolProtocolID", "ProtocolID", "MessageHash", "Connector", "TX", "Created"}, JSONOutputValue: func() interface{} { return &fftypes.TokenTransfer{} }, JSONOutputCodes: []int{http.StatusAccepted, http.StatusOK}, JSONHandler: func(r *oapispec.APIRequest) (output interface{}, err error) { diff --git a/internal/assets/manager.go b/internal/assets/manager.go index 0c67694cd7..94e86afc97 100644 --- a/internal/assets/manager.go +++ b/internal/assets/manager.go @@ -35,19 +35,19 @@ import ( ) type Manager interface { - CreateTokenPool(ctx context.Context, ns, typeName string, pool *fftypes.TokenPool, waitConfirm bool) (*fftypes.TokenPool, error) + CreateTokenPool(ctx context.Context, ns, connector string, pool *fftypes.TokenPool, waitConfirm bool) (*fftypes.TokenPool, error) GetTokenPools(ctx context.Context, ns string, filter database.AndFilter) ([]*fftypes.TokenPool, *database.FilterResult, error) - GetTokenPoolsByType(ctx context.Context, ns, typeName string, filter database.AndFilter) ([]*fftypes.TokenPool, *database.FilterResult, error) - GetTokenPool(ctx context.Context, ns, typeName, poolName string) (*fftypes.TokenPool, error) + GetTokenPoolsByType(ctx context.Context, ns, connector string, filter database.AndFilter) ([]*fftypes.TokenPool, *database.FilterResult, error) + GetTokenPool(ctx context.Context, ns, connector, poolName string) (*fftypes.TokenPool, error) ValidateTokenPoolTx(ctx context.Context, pool *fftypes.TokenPool, protocolTxID string) error GetTokenAccounts(ctx context.Context, ns string, filter database.AndFilter) ([]*fftypes.TokenAccount, *database.FilterResult, error) - GetTokenAccountsByPool(ctx context.Context, ns, typeName, poolName string, filter database.AndFilter) ([]*fftypes.TokenAccount, *database.FilterResult, error) + GetTokenAccountsByPool(ctx context.Context, ns, connector, poolName string, filter database.AndFilter) ([]*fftypes.TokenAccount, *database.FilterResult, error) GetTokenTransfers(ctx context.Context, ns string, filter database.AndFilter) ([]*fftypes.TokenTransfer, *database.FilterResult, error) - GetTokenTransfersByPool(ctx context.Context, ns, typeName, poolName string, filter database.AndFilter) ([]*fftypes.TokenTransfer, *database.FilterResult, error) - NewTransfer(ns, typeName, poolName string, transfer *fftypes.TokenTransferInput) sysmessaging.MessageSender - MintTokens(ctx context.Context, ns, typeName, poolName string, transfer *fftypes.TokenTransferInput, waitConfirm bool) (*fftypes.TokenTransfer, error) - BurnTokens(ctx context.Context, ns, typeName, poolName string, transfer *fftypes.TokenTransferInput, waitConfirm bool) (*fftypes.TokenTransfer, error) - TransferTokens(ctx context.Context, ns, typeName, poolName string, transfer *fftypes.TokenTransferInput, waitConfirm bool) (*fftypes.TokenTransfer, error) + GetTokenTransfersByPool(ctx context.Context, ns, connector, poolName string, filter database.AndFilter) ([]*fftypes.TokenTransfer, *database.FilterResult, error) + NewTransfer(ns, connector, poolName string, transfer *fftypes.TokenTransferInput) sysmessaging.MessageSender + MintTokens(ctx context.Context, ns, connector, poolName string, transfer *fftypes.TokenTransferInput, waitConfirm bool) (*fftypes.TokenTransfer, error) + BurnTokens(ctx context.Context, ns, connector, poolName string, transfer *fftypes.TokenTransferInput, waitConfirm bool) (*fftypes.TokenTransfer, error) + TransferTokens(ctx context.Context, ns, connector, poolName string, transfer *fftypes.TokenTransferInput, waitConfirm bool) (*fftypes.TokenTransfer, error) GetTokenConnectors(ctx context.Context, ns string) ([]*fftypes.TokenConnector, error) // Bound token callbacks @@ -110,8 +110,8 @@ func (am *assetManager) GetTokenAccounts(ctx context.Context, ns string, filter return am.database.GetTokenAccounts(ctx, filter) } -func (am *assetManager) GetTokenAccountsByPool(ctx context.Context, ns, typeName, poolName string, filter database.AndFilter) ([]*fftypes.TokenAccount, *database.FilterResult, error) { - pool, err := am.GetTokenPool(ctx, ns, typeName, poolName) +func (am *assetManager) GetTokenAccountsByPool(ctx context.Context, ns, connector, poolName string, filter database.AndFilter) ([]*fftypes.TokenAccount, *database.FilterResult, error) { + pool, err := am.GetTokenPool(ctx, ns, connector, poolName) if err != nil { return nil, nil, err } diff --git a/internal/assets/token_pool.go b/internal/assets/token_pool.go index 90d7b6545e..d16eb442a5 100644 --- a/internal/assets/token_pool.go +++ b/internal/assets/token_pool.go @@ -49,11 +49,11 @@ func retrieveTokenPoolCreateInputs(ctx context.Context, op *fftypes.Operation, p return nil } -func (am *assetManager) CreateTokenPool(ctx context.Context, ns string, typeName string, pool *fftypes.TokenPool, waitConfirm bool) (*fftypes.TokenPool, error) { - return am.createTokenPoolWithID(ctx, fftypes.NewUUID(), ns, typeName, pool, waitConfirm) +func (am *assetManager) CreateTokenPool(ctx context.Context, ns string, connector string, pool *fftypes.TokenPool, waitConfirm bool) (*fftypes.TokenPool, error) { + return am.createTokenPoolWithID(ctx, fftypes.NewUUID(), ns, connector, pool, waitConfirm) } -func (am *assetManager) createTokenPoolWithID(ctx context.Context, id *fftypes.UUID, ns string, typeName string, pool *fftypes.TokenPool, waitConfirm bool) (*fftypes.TokenPool, error) { +func (am *assetManager) createTokenPoolWithID(ctx context.Context, id *fftypes.UUID, ns string, connector string, pool *fftypes.TokenPool, waitConfirm bool) (*fftypes.TokenPool, error) { if err := am.data.VerifyNamespaceExists(ctx, ns); err != nil { return nil, err } @@ -66,15 +66,19 @@ func (am *assetManager) createTokenPoolWithID(ctx context.Context, id *fftypes.U pool.Key = org.Identity } - plugin, err := am.selectTokenPlugin(ctx, typeName) + plugin, err := am.selectTokenPlugin(ctx, connector) if err != nil { return nil, err } + pool.ID = id + pool.Namespace = ns + pool.Connector = connector + if waitConfirm { requestID := fftypes.NewUUID() return am.syncasync.SendConfirmTokenPool(ctx, ns, requestID, func(ctx context.Context) error { - _, err := am.createTokenPoolWithID(ctx, requestID, ns, typeName, pool, false) + _, err := am.createTokenPoolWithID(ctx, requestID, ns, connector, pool, false) return err }) } @@ -96,8 +100,6 @@ func (am *assetManager) createTokenPoolWithID(ctx context.Context, id *fftypes.U return nil, err } - pool.ID = id - pool.Namespace = ns pool.TX.ID = tx.ID pool.TX.Type = tx.Subject.Type @@ -125,8 +127,8 @@ func (am *assetManager) GetTokenPools(ctx context.Context, ns string, filter dat return am.database.GetTokenPools(ctx, am.scopeNS(ns, filter)) } -func (am *assetManager) GetTokenPoolsByType(ctx context.Context, ns string, typeName string, filter database.AndFilter) ([]*fftypes.TokenPool, *database.FilterResult, error) { - if _, err := am.selectTokenPlugin(ctx, typeName); err != nil { +func (am *assetManager) GetTokenPoolsByType(ctx context.Context, ns string, connector string, filter database.AndFilter) ([]*fftypes.TokenPool, *database.FilterResult, error) { + if _, err := am.selectTokenPlugin(ctx, connector); err != nil { return nil, nil, err } if err := fftypes.ValidateFFNameField(ctx, ns, "namespace"); err != nil { @@ -135,8 +137,8 @@ func (am *assetManager) GetTokenPoolsByType(ctx context.Context, ns string, type return am.database.GetTokenPools(ctx, am.scopeNS(ns, filter)) } -func (am *assetManager) GetTokenPool(ctx context.Context, ns, typeName, poolName string) (*fftypes.TokenPool, error) { - if _, err := am.selectTokenPlugin(ctx, typeName); err != nil { +func (am *assetManager) GetTokenPool(ctx context.Context, ns, connector, poolName string) (*fftypes.TokenPool, error) { + if _, err := am.selectTokenPlugin(ctx, connector); err != nil { return nil, err } if err := fftypes.ValidateFFNameField(ctx, ns, "namespace"); err != nil { diff --git a/internal/assets/token_transfer.go b/internal/assets/token_transfer.go index 5e7e0d86bc..51758a70e5 100644 --- a/internal/assets/token_transfer.go +++ b/internal/assets/token_transfer.go @@ -37,19 +37,19 @@ func (am *assetManager) GetTokenTransfers(ctx context.Context, ns string, filter return am.database.GetTokenTransfers(ctx, filter) } -func (am *assetManager) GetTokenTransfersByPool(ctx context.Context, ns, typeName, name string, filter database.AndFilter) ([]*fftypes.TokenTransfer, *database.FilterResult, error) { - pool, err := am.GetTokenPool(ctx, ns, typeName, name) +func (am *assetManager) GetTokenTransfersByPool(ctx context.Context, ns, connector, name string, filter database.AndFilter) ([]*fftypes.TokenTransfer, *database.FilterResult, error) { + pool, err := am.GetTokenPool(ctx, ns, connector, name) if err != nil { return nil, nil, err } return am.database.GetTokenTransfers(ctx, filter.Condition(filter.Builder().Eq("poolprotocolid", pool.ProtocolID))) } -func (am *assetManager) NewTransfer(ns, typeName, poolName string, transfer *fftypes.TokenTransferInput) sysmessaging.MessageSender { +func (am *assetManager) NewTransfer(ns, connector, poolName string, transfer *fftypes.TokenTransferInput) sysmessaging.MessageSender { sender := &transferSender{ mgr: am, namespace: ns, - typeName: typeName, + connector: connector, poolName: poolName, transfer: transfer, } @@ -60,7 +60,7 @@ func (am *assetManager) NewTransfer(ns, typeName, poolName string, transfer *fft type transferSender struct { mgr *assetManager namespace string - typeName string + connector string poolName string transfer *fftypes.TokenTransferInput sendCallback sysmessaging.BeforeSendCallback @@ -81,9 +81,10 @@ func (s *transferSender) BeforeSend(cb sysmessaging.BeforeSendCallback) sysmessa func (s *transferSender) setDefaults() { s.transfer.LocalID = fftypes.NewUUID() + s.transfer.Connector = s.connector } -func (am *assetManager) MintTokens(ctx context.Context, ns, typeName, poolName string, transfer *fftypes.TokenTransferInput, waitConfirm bool) (out *fftypes.TokenTransfer, err error) { +func (am *assetManager) MintTokens(ctx context.Context, ns, connector, poolName string, transfer *fftypes.TokenTransferInput, waitConfirm bool) (out *fftypes.TokenTransfer, err error) { transfer.Type = fftypes.TokenTransferTypeMint if transfer.Key == "" { org, err := am.identity.GetLocalOrganization(ctx) @@ -97,7 +98,7 @@ func (am *assetManager) MintTokens(ctx context.Context, ns, typeName, poolName s transfer.To = transfer.Key } - sender := am.NewTransfer(ns, typeName, poolName, transfer) + sender := am.NewTransfer(ns, connector, poolName, transfer) if waitConfirm { err = sender.SendAndWait(ctx) } else { @@ -106,7 +107,7 @@ func (am *assetManager) MintTokens(ctx context.Context, ns, typeName, poolName s return &transfer.TokenTransfer, err } -func (am *assetManager) BurnTokens(ctx context.Context, ns, typeName, poolName string, transfer *fftypes.TokenTransferInput, waitConfirm bool) (out *fftypes.TokenTransfer, err error) { +func (am *assetManager) BurnTokens(ctx context.Context, ns, connector, poolName string, transfer *fftypes.TokenTransferInput, waitConfirm bool) (out *fftypes.TokenTransfer, err error) { transfer.Type = fftypes.TokenTransferTypeBurn if transfer.Key == "" { org, err := am.identity.GetLocalOrganization(ctx) @@ -120,7 +121,7 @@ func (am *assetManager) BurnTokens(ctx context.Context, ns, typeName, poolName s } transfer.To = "" - sender := am.NewTransfer(ns, typeName, poolName, transfer) + sender := am.NewTransfer(ns, connector, poolName, transfer) if waitConfirm { err = sender.SendAndWait(ctx) } else { @@ -129,7 +130,7 @@ func (am *assetManager) BurnTokens(ctx context.Context, ns, typeName, poolName s return &transfer.TokenTransfer, err } -func (am *assetManager) TransferTokens(ctx context.Context, ns, typeName, poolName string, transfer *fftypes.TokenTransferInput, waitConfirm bool) (out *fftypes.TokenTransfer, err error) { +func (am *assetManager) TransferTokens(ctx context.Context, ns, connector, poolName string, transfer *fftypes.TokenTransferInput, waitConfirm bool) (out *fftypes.TokenTransfer, err error) { transfer.Type = fftypes.TokenTransferTypeTransfer if transfer.Key == "" { org, err := am.identity.GetLocalOrganization(ctx) @@ -148,7 +149,7 @@ func (am *assetManager) TransferTokens(ctx context.Context, ns, typeName, poolNa return nil, i18n.NewError(ctx, i18n.MsgCannotTransferToSelf) } - sender := am.NewTransfer(ns, typeName, poolName, transfer) + sender := am.NewTransfer(ns, connector, poolName, transfer) if waitConfirm { err = sender.SendAndWait(ctx) } else { @@ -158,11 +159,11 @@ func (am *assetManager) TransferTokens(ctx context.Context, ns, typeName, poolNa } func (s *transferSender) resolveAndSend(ctx context.Context, waitConfirm bool) (err error) { - plugin, err := s.mgr.selectTokenPlugin(ctx, s.typeName) + plugin, err := s.mgr.selectTokenPlugin(ctx, s.connector) if err != nil { return err } - pool, err := s.mgr.GetTokenPool(ctx, s.namespace, s.typeName, s.poolName) + pool, err := s.mgr.GetTokenPool(ctx, s.namespace, s.connector, s.poolName) if err != nil { return err } diff --git a/internal/assets/token_transfer_test.go b/internal/assets/token_transfer_test.go index 3018cce8d6..543481bc52 100644 --- a/internal/assets/token_transfer_test.go +++ b/internal/assets/token_transfer_test.go @@ -395,7 +395,7 @@ func TestTransferTokensInvalidType(t *testing.T) { sender := &transferSender{ mgr: am, namespace: "ns1", - typeName: "magic-tokens", + connector: "magic-tokens", poolName: "pool1", transfer: transfer, } diff --git a/internal/database/sqlcommon/tokenaccount_sql.go b/internal/database/sqlcommon/tokenaccount_sql.go index bda07ab062..72284a2de3 100644 --- a/internal/database/sqlcommon/tokenaccount_sql.go +++ b/internal/database/sqlcommon/tokenaccount_sql.go @@ -31,6 +31,7 @@ var ( tokenAccountColumns = []string{ "pool_protocol_id", "token_index", + "connector", "identity", "balance", } @@ -90,6 +91,7 @@ func (s *SQLCommon) AddTokenAccountBalance(ctx context.Context, account *fftypes Values( account.PoolProtocolID, account.TokenIndex, + account.Connector, account.Identity, account.Amount, ), @@ -107,6 +109,7 @@ func (s *SQLCommon) tokenAccountResult(ctx context.Context, row *sql.Rows) (*fft err := row.Scan( &account.PoolProtocolID, &account.TokenIndex, + &account.Connector, &account.Identity, &account.Balance, ) diff --git a/internal/database/sqlcommon/tokenaccount_sql_test.go b/internal/database/sqlcommon/tokenaccount_sql_test.go index 1a80df0d2a..052f5604d2 100644 --- a/internal/database/sqlcommon/tokenaccount_sql_test.go +++ b/internal/database/sqlcommon/tokenaccount_sql_test.go @@ -39,12 +39,14 @@ func TestTokenAccountE2EWithDB(t *testing.T) { operation := &fftypes.TokenBalanceChange{ PoolProtocolID: "F1", TokenIndex: "1", + Connector: "erc1155", Identity: "0x0", } operation.Amount.Int().SetInt64(10) account := &fftypes.TokenAccount{ PoolProtocolID: "F1", TokenIndex: "1", + Connector: "erc1155", Identity: "0x0", } account.Balance.Int().SetInt64(10) @@ -158,6 +160,7 @@ func TestAddTokenAccountBalanceInsertSuccess(t *testing.T) { operation := &fftypes.TokenBalanceChange{ PoolProtocolID: "F1", TokenIndex: "1", + Connector: "erc1155", Identity: "0x0", } operation.Amount.Int().SetInt64(10) @@ -165,7 +168,7 @@ func TestAddTokenAccountBalanceInsertSuccess(t *testing.T) { db.ExpectBegin() db.ExpectQuery("SELECT .*").WillReturnRows(sqlmock.NewRows([]string{"id"})) db.ExpectExec("INSERT .*"). - WithArgs("F1", "1", "0x0", sqlmock.AnyArg()). + WithArgs("F1", "1", "erc1155", "0x0", sqlmock.AnyArg()). WillReturnResult(sqlmock.NewResult(1, 1)) db.ExpectCommit() err := s.AddTokenAccountBalance(context.Background(), operation) diff --git a/internal/database/sqlcommon/tokentransfer_sql.go b/internal/database/sqlcommon/tokentransfer_sql.go index de163d06f2..ffc1e5bf35 100644 --- a/internal/database/sqlcommon/tokentransfer_sql.go +++ b/internal/database/sqlcommon/tokentransfer_sql.go @@ -33,6 +33,7 @@ var ( "local_id", "pool_protocol_id", "token_index", + "connector", "key", "from_key", "to_key", @@ -81,6 +82,7 @@ func (s *SQLCommon) UpsertTokenTransfer(ctx context.Context, transfer *fftypes.T Set("local_id", transfer.LocalID). Set("pool_protocol_id", transfer.PoolProtocolID). Set("token_index", transfer.TokenIndex). + Set("connector", transfer.Connector). Set("key", transfer.Key). Set("from_key", transfer.From). Set("to_key", transfer.To). @@ -105,6 +107,7 @@ func (s *SQLCommon) UpsertTokenTransfer(ctx context.Context, transfer *fftypes.T transfer.LocalID, transfer.PoolProtocolID, transfer.TokenIndex, + transfer.Connector, transfer.Key, transfer.From, transfer.To, @@ -133,6 +136,7 @@ func (s *SQLCommon) tokenTransferResult(ctx context.Context, row *sql.Rows) (*ff &transfer.LocalID, &transfer.PoolProtocolID, &transfer.TokenIndex, + &transfer.Connector, &transfer.Key, &transfer.From, &transfer.To, diff --git a/internal/database/sqlcommon/tokentransfer_sql_test.go b/internal/database/sqlcommon/tokentransfer_sql_test.go index a355c31a8d..93c70f5b2d 100644 --- a/internal/database/sqlcommon/tokentransfer_sql_test.go +++ b/internal/database/sqlcommon/tokentransfer_sql_test.go @@ -40,6 +40,7 @@ func TestTokenTransferE2EWithDB(t *testing.T) { Type: fftypes.TokenTransferTypeTransfer, PoolProtocolID: "F1", TokenIndex: "1", + Connector: "erc1155", From: "0x01", To: "0x02", ProtocolID: "12345", diff --git a/internal/events/tokens_transferred.go b/internal/events/tokens_transferred.go index 82d1966857..e34ae4d36d 100644 --- a/internal/events/tokens_transferred.go +++ b/internal/events/tokens_transferred.go @@ -119,6 +119,7 @@ func (em *eventManager) TokensTransferred(tk tokens.Plugin, transfer *fftypes.To balance := &fftypes.TokenBalanceChange{ PoolProtocolID: transfer.PoolProtocolID, TokenIndex: transfer.TokenIndex, + Connector: transfer.Connector, } if transfer.Type != fftypes.TokenTransferTypeMint { diff --git a/internal/tokens/fftokens/config.go b/internal/tokens/fftokens/config.go index 8c01a935b0..66e00cea47 100644 --- a/internal/tokens/fftokens/config.go +++ b/internal/tokens/fftokens/config.go @@ -21,6 +21,6 @@ import ( "github.com/hyperledger/firefly/internal/config/wsconfig" ) -func (h *FFTokens) InitPrefix(prefix config.PrefixArray) { +func (ft *FFTokens) InitPrefix(prefix config.PrefixArray) { wsconfig.InitPrefix(prefix) } diff --git a/internal/tokens/fftokens/fftokens.go b/internal/tokens/fftokens/fftokens.go index fd353f3452..6d11a4be44 100644 --- a/internal/tokens/fftokens/fftokens.go +++ b/internal/tokens/fftokens/fftokens.go @@ -91,21 +91,21 @@ type transferTokens struct { Data string `json:"data,omitempty"` } -func (h *FFTokens) Name() string { +func (ft *FFTokens) Name() string { return "fftokens" } -func (h *FFTokens) Init(ctx context.Context, name string, prefix config.Prefix, callbacks tokens.Callbacks) (err error) { - h.ctx = log.WithLogField(ctx, "proto", "fftokens") - h.callbacks = callbacks - h.configuredName = name +func (ft *FFTokens) Init(ctx context.Context, name string, prefix config.Prefix, callbacks tokens.Callbacks) (err error) { + ft.ctx = log.WithLogField(ctx, "proto", "fftokens") + ft.callbacks = callbacks + ft.configuredName = name if prefix.GetString(restclient.HTTPConfigURL) == "" { return i18n.NewError(ctx, i18n.MsgMissingPluginConfig, "url", "tokens.fftokens") } - h.client = restclient.New(h.ctx, prefix) - h.capabilities = &tokens.Capabilities{} + ft.client = restclient.New(ft.ctx, prefix) + ft.capabilities = &tokens.Capabilities{} wsConfig := wsconfig.GenerateConfigFromPrefix(prefix) @@ -113,25 +113,25 @@ func (h *FFTokens) Init(ctx context.Context, name string, prefix config.Prefix, wsConfig.WSKeyPath = "/api/ws" } - h.wsconn, err = wsclient.New(ctx, wsConfig, nil) + ft.wsconn, err = wsclient.New(ctx, wsConfig, nil) if err != nil { return err } - go h.eventLoop() + go ft.eventLoop() return nil } -func (h *FFTokens) Start() error { - return h.wsconn.Connect() +func (ft *FFTokens) Start() error { + return ft.wsconn.Connect() } -func (h *FFTokens) Capabilities() *tokens.Capabilities { - return h.capabilities +func (ft *FFTokens) Capabilities() *tokens.Capabilities { + return ft.capabilities } -func (h *FFTokens) handleReceipt(ctx context.Context, data fftypes.JSONObject) error { +func (ft *FFTokens) handleReceipt(ctx context.Context, data fftypes.JSONObject) error { l := log.L(ctx) requestID := data.GetString("id") @@ -151,10 +151,10 @@ func (h *FFTokens) handleReceipt(ctx context.Context, data fftypes.JSONObject) e replyType = fftypes.OpStatusFailed } l.Infof("Tokens '%s' reply: request=%s message=%s", replyType, requestID, message) - return h.callbacks.TokensOpUpdate(h, operationID, replyType, message, data) + return ft.callbacks.TokensOpUpdate(ft, operationID, replyType, message, data) } -func (h *FFTokens) handleTokenPoolCreate(ctx context.Context, data fftypes.JSONObject) (err error) { +func (ft *FFTokens) handleTokenPoolCreate(ctx context.Context, data fftypes.JSONObject) (err error) { tokenType := data.GetString("type") protocolID := data.GetString("poolId") trackingID := data.GetString("trackingId") @@ -180,6 +180,7 @@ func (h *FFTokens) handleTokenPoolCreate(ctx context.Context, data fftypes.JSONO pool := &fftypes.TokenPool{ Type: fftypes.FFEnum(tokenType), ProtocolID: protocolID, + Connector: ft.configuredName, Key: operatorAddress, TX: fftypes.TransactionRef{ ID: txID, @@ -188,10 +189,10 @@ func (h *FFTokens) handleTokenPoolCreate(ctx context.Context, data fftypes.JSONO } // If there's an error dispatching the event, we must return the error and shutdown - return h.callbacks.TokenPoolCreated(h, pool, txHash, tx) + return ft.callbacks.TokenPoolCreated(ft, pool, txHash, tx) } -func (h *FFTokens) handleTokenTransfer(ctx context.Context, t fftypes.TokenTransferType, data fftypes.JSONObject) (err error) { +func (ft *FFTokens) handleTokenTransfer(ctx context.Context, t fftypes.TokenTransferType, data fftypes.JSONObject) (err error) { tokenIndex := data.GetString("tokenIndex") poolProtocolID := data.GetString("poolId") operatorAddress := data.GetString("operator") @@ -243,6 +244,7 @@ func (h *FFTokens) handleTokenTransfer(ctx context.Context, t fftypes.TokenTrans Type: t, PoolProtocolID: poolProtocolID, TokenIndex: tokenIndex, + Connector: ft.configuredName, From: fromAddress, To: toAddress, ProtocolID: txHash, @@ -261,19 +263,19 @@ func (h *FFTokens) handleTokenTransfer(ctx context.Context, t fftypes.TokenTrans } // If there's an error dispatching the event, we must return the error and shutdown - return h.callbacks.TokensTransferred(h, transfer, txHash, tx) + return ft.callbacks.TokensTransferred(ft, transfer, txHash, tx) } -func (h *FFTokens) eventLoop() { - defer h.wsconn.Close() - l := log.L(h.ctx).WithField("role", "event-loop") - ctx := log.WithLogger(h.ctx, l) +func (ft *FFTokens) eventLoop() { + defer ft.wsconn.Close() + l := log.L(ft.ctx).WithField("role", "event-loop") + ctx := log.WithLogger(ft.ctx, l) for { select { case <-ctx.Done(): l.Debugf("Event loop exiting (context cancelled)") return - case msgBytes, ok := <-h.wsconn.Receive(): + case msgBytes, ok := <-ft.wsconn.Receive(): if !ok { l.Debugf("Event loop exiting (receive channel closed)") return @@ -288,15 +290,15 @@ func (h *FFTokens) eventLoop() { l.Debugf("Received %s event %s", msg.Event, msg.ID) switch msg.Event { case messageReceipt: - err = h.handleReceipt(ctx, msg.Data) + err = ft.handleReceipt(ctx, msg.Data) case messageTokenPool: - err = h.handleTokenPoolCreate(ctx, msg.Data) + err = ft.handleTokenPoolCreate(ctx, msg.Data) case messageTokenMint: - err = h.handleTokenTransfer(ctx, fftypes.TokenTransferTypeMint, msg.Data) + err = ft.handleTokenTransfer(ctx, fftypes.TokenTransferTypeMint, msg.Data) case messageTokenBurn: - err = h.handleTokenTransfer(ctx, fftypes.TokenTransferTypeBurn, msg.Data) + err = ft.handleTokenTransfer(ctx, fftypes.TokenTransferTypeBurn, msg.Data) case messageTokenTransfer: - err = h.handleTokenTransfer(ctx, fftypes.TokenTransferTypeTransfer, msg.Data) + err = ft.handleTokenTransfer(ctx, fftypes.TokenTransferTypeTransfer, msg.Data) default: l.Errorf("Message unexpected: %s", msg.Event) } @@ -309,7 +311,7 @@ func (h *FFTokens) eventLoop() { "id": msg.ID, }, }) - err = h.wsconn.Send(ctx, ack) + err = ft.wsconn.Send(ctx, ack) } if err != nil { @@ -320,8 +322,8 @@ func (h *FFTokens) eventLoop() { } } -func (h *FFTokens) CreateTokenPool(ctx context.Context, operationID *fftypes.UUID, pool *fftypes.TokenPool) error { - res, err := h.client.R().SetContext(ctx). +func (ft *FFTokens) CreateTokenPool(ctx context.Context, operationID *fftypes.UUID, pool *fftypes.TokenPool) error { + res, err := ft.client.R().SetContext(ctx). SetBody(&createPool{ Type: pool.Type, RequestID: operationID.String(), @@ -335,8 +337,8 @@ func (h *FFTokens) CreateTokenPool(ctx context.Context, operationID *fftypes.UUI return nil } -func (h *FFTokens) MintTokens(ctx context.Context, operationID *fftypes.UUID, mint *fftypes.TokenTransfer) error { - res, err := h.client.R().SetContext(ctx). +func (ft *FFTokens) MintTokens(ctx context.Context, operationID *fftypes.UUID, mint *fftypes.TokenTransfer) error { + res, err := ft.client.R().SetContext(ctx). SetBody(&mintTokens{ PoolID: mint.PoolProtocolID, To: mint.To, @@ -351,8 +353,8 @@ func (h *FFTokens) MintTokens(ctx context.Context, operationID *fftypes.UUID, mi return nil } -func (h *FFTokens) BurnTokens(ctx context.Context, operationID *fftypes.UUID, burn *fftypes.TokenTransfer) error { - res, err := h.client.R().SetContext(ctx). +func (ft *FFTokens) BurnTokens(ctx context.Context, operationID *fftypes.UUID, burn *fftypes.TokenTransfer) error { + res, err := ft.client.R().SetContext(ctx). SetBody(&burnTokens{ PoolID: burn.PoolProtocolID, TokenIndex: burn.TokenIndex, @@ -368,8 +370,8 @@ func (h *FFTokens) BurnTokens(ctx context.Context, operationID *fftypes.UUID, bu return nil } -func (h *FFTokens) TransferTokens(ctx context.Context, operationID *fftypes.UUID, transfer *fftypes.TokenTransfer) error { - res, err := h.client.R().SetContext(ctx). +func (ft *FFTokens) TransferTokens(ctx context.Context, operationID *fftypes.UUID, transfer *fftypes.TokenTransfer) error { + res, err := ft.client.R().SetContext(ctx). SetBody(&transferTokens{ PoolID: transfer.PoolProtocolID, TokenIndex: transfer.TokenIndex, diff --git a/pkg/database/plugin.go b/pkg/database/plugin.go index ea2f466b9a..a142bf1758 100644 --- a/pkg/database/plugin.go +++ b/pkg/database/plugin.go @@ -775,6 +775,7 @@ var TokenPoolQueryFactory = &queryFields{ var TokenAccountQueryFactory = &queryFields{ "poolprotocolid": &StringField{}, "tokenindex": &StringField{}, + "connector": &StringField{}, "identity": &StringField{}, "balance": &Int64Field{}, } @@ -784,6 +785,7 @@ var TokenTransferQueryFactory = &queryFields{ "localid": &StringField{}, "poolprotocolid": &StringField{}, "tokenindex": &StringField{}, + "connector": &StringField{}, "key": &StringField{}, "from": &StringField{}, "to": &StringField{}, diff --git a/pkg/fftypes/tokenaccount.go b/pkg/fftypes/tokenaccount.go index 4b6217d627..e0071cf320 100644 --- a/pkg/fftypes/tokenaccount.go +++ b/pkg/fftypes/tokenaccount.go @@ -19,6 +19,7 @@ package fftypes type TokenAccount struct { PoolProtocolID string `json:"poolProtocolId,omitempty"` TokenIndex string `json:"tokenIndex,omitempty"` + Connector string `json:"connector,omitempty"` Identity string `json:"identity,omitempty"` Balance BigInt `json:"balance"` } @@ -34,6 +35,7 @@ func (t *TokenAccount) Identifier() string { type TokenBalanceChange struct { PoolProtocolID string TokenIndex string + Connector string Identity string Amount BigInt } diff --git a/pkg/fftypes/tokentransfer.go b/pkg/fftypes/tokentransfer.go index 22136cf30a..47e2c437b9 100644 --- a/pkg/fftypes/tokentransfer.go +++ b/pkg/fftypes/tokentransfer.go @@ -29,6 +29,7 @@ type TokenTransfer struct { LocalID *UUID `json:"localId,omitempty"` PoolProtocolID string `json:"poolProtocolId,omitempty"` TokenIndex string `json:"tokenIndex,omitempty"` + Connector string `json:"connector,omitempty"` Key string `json:"key,omitempty"` From string `json:"from,omitempty"` To string `json:"to,omitempty"` diff --git a/test/e2e/e2e_test.go b/test/e2e/e2e_test.go index 416a2082a1..4713c6d319 100644 --- a/test/e2e/e2e_test.go +++ b/test/e2e/e2e_test.go @@ -132,6 +132,7 @@ func validateReceivedMessages(ts *testState, client *resty.Client, msgType fftyp func validateAccountBalances(t *testing.T, client *resty.Client, poolName, tokenIndex string, balances map[string]int64) { for identity, balance := range balances { account := GetTokenAccount(t, client, poolName, tokenIndex, identity) + assert.Equal(t, "erc1155", account.Connector) assert.Equal(t, balance, account.Balance.Int().Int64()) } } @@ -505,6 +506,7 @@ func TestE2ETokenPool(t *testing.T) { pools = GetTokenPools(t, ts.client1, ts.startTime) assert.Equal(t, 1, len(pools)) assert.Equal(t, "default", pools[0].Namespace) + assert.Equal(t, "erc1155", pools[0].Connector) assert.Equal(t, poolName, pools[0].Name) assert.Equal(t, fftypes.TokenTypeFungible, pools[0].Type) @@ -512,6 +514,7 @@ func TestE2ETokenPool(t *testing.T) { pools = GetTokenPools(t, ts.client1, ts.startTime) assert.Equal(t, 1, len(pools)) assert.Equal(t, "default", pools[0].Namespace) + assert.Equal(t, "erc1155", pools[0].Connector) assert.Equal(t, poolName, pools[0].Name) assert.Equal(t, fftypes.TokenTypeFungible, pools[0].Type) @@ -522,6 +525,7 @@ func TestE2ETokenPool(t *testing.T) { <-received1 transfers := GetTokenTransfers(t, ts.client1, poolName) assert.Equal(t, 1, len(transfers)) + assert.Equal(t, "erc1155", transfers[0].Connector) assert.Equal(t, fftypes.TokenTransferTypeMint, transfers[0].Type) assert.Equal(t, int64(1), transfers[0].Amount.Int().Int64()) validateAccountBalances(t, ts.client1, poolName, "", map[string]int64{ @@ -531,6 +535,7 @@ func TestE2ETokenPool(t *testing.T) { <-received2 transfers = GetTokenTransfers(t, ts.client2, poolName) assert.Equal(t, 1, len(transfers)) + assert.Equal(t, "erc1155", transfers[0].Connector) assert.Equal(t, fftypes.TokenTransferTypeMint, transfers[0].Type) assert.Equal(t, int64(1), transfers[0].Amount.Int().Int64()) validateAccountBalances(t, ts.client2, poolName, "", map[string]int64{ @@ -546,6 +551,7 @@ func TestE2ETokenPool(t *testing.T) { <-received1 transfers = GetTokenTransfers(t, ts.client1, poolName) assert.Equal(t, 2, len(transfers)) + assert.Equal(t, "erc1155", transfers[0].Connector) assert.Equal(t, fftypes.TokenTransferTypeTransfer, transfers[0].Type) assert.Equal(t, int64(1), transfers[0].Amount.Int().Int64()) validateAccountBalances(t, ts.client1, poolName, "", map[string]int64{ @@ -556,6 +562,7 @@ func TestE2ETokenPool(t *testing.T) { <-received2 transfers = GetTokenTransfers(t, ts.client2, poolName) assert.Equal(t, 2, len(transfers)) + assert.Equal(t, "erc1155", transfers[0].Connector) assert.Equal(t, fftypes.TokenTransferTypeTransfer, transfers[0].Type) assert.Equal(t, int64(1), transfers[0].Amount.Int().Int64()) validateAccountBalances(t, ts.client2, poolName, "", map[string]int64{ @@ -570,6 +577,7 @@ func TestE2ETokenPool(t *testing.T) { <-received2 transfers = GetTokenTransfers(t, ts.client2, poolName) assert.Equal(t, 3, len(transfers)) + assert.Equal(t, "erc1155", transfers[0].Connector) assert.Equal(t, fftypes.TokenTransferTypeBurn, transfers[0].Type) assert.Equal(t, int64(1), transfers[0].Amount.Int().Int64()) validateAccountBalances(t, ts.client2, poolName, "", map[string]int64{ @@ -580,6 +588,7 @@ func TestE2ETokenPool(t *testing.T) { <-received1 transfers = GetTokenTransfers(t, ts.client1, poolName) assert.Equal(t, 3, len(transfers)) + assert.Equal(t, "erc1155", transfers[0].Connector) assert.Equal(t, fftypes.TokenTransferTypeBurn, transfers[0].Type) assert.Equal(t, int64(1), transfers[0].Amount.Int().Int64()) validateAccountBalances(t, ts.client1, poolName, "", map[string]int64{ From 2b6ce6a21ac9eb23ac70501d2c3c98d49b93deb9 Mon Sep 17 00:00:00 2001 From: Andrew Richardson Date: Tue, 19 Oct 2021 15:24:37 -0400 Subject: [PATCH 2/4] Rename tokenaccount "identity" field to "key" for consistency Signed-off-by: Andrew Richardson --- .../000034_rename_tokenaccount_key.down.sql | 3 +++ .../000034_rename_tokenaccount_key.up.sql | 3 +++ .../000034_rename_tokenaccount_key.down.sql | 1 + .../sqlite/000034_rename_tokenaccount_key.up.sql | 1 + docs/swagger/swagger.yaml | 8 ++++---- internal/database/sqlcommon/tokenaccount_sql.go | 16 ++++++++-------- .../database/sqlcommon/tokenaccount_sql_test.go | 10 +++++----- internal/events/tokens_transferred.go | 8 ++++---- internal/events/tokens_transferred_test.go | 8 ++++---- pkg/database/plugin.go | 2 +- pkg/fftypes/tokenaccount.go | 6 +++--- pkg/fftypes/tokenaccount_test.go | 2 +- test/e2e/e2e_test.go | 4 ++-- test/e2e/restclient.go | 6 +++--- 14 files changed, 43 insertions(+), 35 deletions(-) create mode 100644 db/migrations/postgres/000034_rename_tokenaccount_key.down.sql create mode 100644 db/migrations/postgres/000034_rename_tokenaccount_key.up.sql create mode 100644 db/migrations/sqlite/000034_rename_tokenaccount_key.down.sql create mode 100644 db/migrations/sqlite/000034_rename_tokenaccount_key.up.sql diff --git a/db/migrations/postgres/000034_rename_tokenaccount_key.down.sql b/db/migrations/postgres/000034_rename_tokenaccount_key.down.sql new file mode 100644 index 0000000000..f07cf93c7a --- /dev/null +++ b/db/migrations/postgres/000034_rename_tokenaccount_key.down.sql @@ -0,0 +1,3 @@ +BEGIN; +ALTER TABLE tokenaccount RENAME COLUMN key TO identity; +COMMIT; diff --git a/db/migrations/postgres/000034_rename_tokenaccount_key.up.sql b/db/migrations/postgres/000034_rename_tokenaccount_key.up.sql new file mode 100644 index 0000000000..073b61194a --- /dev/null +++ b/db/migrations/postgres/000034_rename_tokenaccount_key.up.sql @@ -0,0 +1,3 @@ +BEGIN; +ALTER TABLE tokenaccount RENAME COLUMN identity TO key; +COMMIT; diff --git a/db/migrations/sqlite/000034_rename_tokenaccount_key.down.sql b/db/migrations/sqlite/000034_rename_tokenaccount_key.down.sql new file mode 100644 index 0000000000..86a43ac556 --- /dev/null +++ b/db/migrations/sqlite/000034_rename_tokenaccount_key.down.sql @@ -0,0 +1 @@ +ALTER TABLE tokenaccount RENAME COLUMN key TO identity; diff --git a/db/migrations/sqlite/000034_rename_tokenaccount_key.up.sql b/db/migrations/sqlite/000034_rename_tokenaccount_key.up.sql new file mode 100644 index 0000000000..9e6365e04c --- /dev/null +++ b/db/migrations/sqlite/000034_rename_tokenaccount_key.up.sql @@ -0,0 +1 @@ +ALTER TABLE tokenaccount RENAME COLUMN identity TO key; diff --git a/docs/swagger/swagger.yaml b/docs/swagger/swagger.yaml index aecb499cff..5018f09420 100644 --- a/docs/swagger/swagger.yaml +++ b/docs/swagger/swagger.yaml @@ -4640,7 +4640,7 @@ paths: type: string - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^' in: query - name: identity + name: key schema: type: string - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^' @@ -4697,7 +4697,7 @@ paths: balance: {} connector: type: string - identity: + key: type: string poolProtocolId: type: string @@ -5580,7 +5580,7 @@ paths: type: string - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^' in: query - name: identity + name: key schema: type: string - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^' @@ -5637,7 +5637,7 @@ paths: balance: {} connector: type: string - identity: + key: type: string poolProtocolId: type: string diff --git a/internal/database/sqlcommon/tokenaccount_sql.go b/internal/database/sqlcommon/tokenaccount_sql.go index 72284a2de3..13cb041009 100644 --- a/internal/database/sqlcommon/tokenaccount_sql.go +++ b/internal/database/sqlcommon/tokenaccount_sql.go @@ -32,7 +32,7 @@ var ( "pool_protocol_id", "token_index", "connector", - "identity", + "key", "balance", } tokenAccountFilterFieldMap = map[string]string{ @@ -54,7 +54,7 @@ func (s *SQLCommon) AddTokenAccountBalance(ctx context.Context, account *fftypes Where(sq.And{ sq.Eq{"pool_protocol_id": account.PoolProtocolID}, sq.Eq{"token_index": account.TokenIndex}, - sq.Eq{"identity": account.Identity}, + sq.Eq{"key": account.Key}, }), ) if err != nil { @@ -78,7 +78,7 @@ func (s *SQLCommon) AddTokenAccountBalance(ctx context.Context, account *fftypes Where(sq.And{ sq.Eq{"pool_protocol_id": account.PoolProtocolID}, sq.Eq{"token_index": account.TokenIndex}, - sq.Eq{"identity": account.Identity}, + sq.Eq{"key": account.Key}, }), nil, ); err != nil { @@ -92,7 +92,7 @@ func (s *SQLCommon) AddTokenAccountBalance(ctx context.Context, account *fftypes account.PoolProtocolID, account.TokenIndex, account.Connector, - account.Identity, + account.Key, account.Amount, ), nil, @@ -110,7 +110,7 @@ func (s *SQLCommon) tokenAccountResult(ctx context.Context, row *sql.Rows) (*fft &account.PoolProtocolID, &account.TokenIndex, &account.Connector, - &account.Identity, + &account.Key, &account.Balance, ) if err != nil { @@ -143,12 +143,12 @@ func (s *SQLCommon) getTokenAccountPred(ctx context.Context, desc string, pred i return account, nil } -func (s *SQLCommon) GetTokenAccount(ctx context.Context, protocolID, tokenIndex, identity string) (message *fftypes.TokenAccount, err error) { - desc := fftypes.TokenAccountIdentifier(protocolID, tokenIndex, identity) +func (s *SQLCommon) GetTokenAccount(ctx context.Context, protocolID, tokenIndex, key string) (message *fftypes.TokenAccount, err error) { + desc := fftypes.TokenAccountIdentifier(protocolID, tokenIndex, key) return s.getTokenAccountPred(ctx, desc, sq.And{ sq.Eq{"pool_protocol_id": protocolID}, sq.Eq{"token_index": tokenIndex}, - sq.Eq{"identity": identity}, + sq.Eq{"key": key}, }) } diff --git a/internal/database/sqlcommon/tokenaccount_sql_test.go b/internal/database/sqlcommon/tokenaccount_sql_test.go index 052f5604d2..271ada9619 100644 --- a/internal/database/sqlcommon/tokenaccount_sql_test.go +++ b/internal/database/sqlcommon/tokenaccount_sql_test.go @@ -40,14 +40,14 @@ func TestTokenAccountE2EWithDB(t *testing.T) { PoolProtocolID: "F1", TokenIndex: "1", Connector: "erc1155", - Identity: "0x0", + Key: "0x0", } operation.Amount.Int().SetInt64(10) account := &fftypes.TokenAccount{ PoolProtocolID: "F1", TokenIndex: "1", Connector: "erc1155", - Identity: "0x0", + Key: "0x0", } account.Balance.Int().SetInt64(10) accountJson, _ := json.Marshal(&account) @@ -67,7 +67,7 @@ func TestTokenAccountE2EWithDB(t *testing.T) { filter := fb.And( fb.Eq("poolprotocolid", account.PoolProtocolID), fb.Eq("tokenindex", account.TokenIndex), - fb.Eq("identity", account.Identity), + fb.Eq("key", account.Key), ) accounts, res, err := s.GetTokenAccounts(ctx, filter.Count(true)) assert.NoError(t, err) @@ -161,7 +161,7 @@ func TestAddTokenAccountBalanceInsertSuccess(t *testing.T) { PoolProtocolID: "F1", TokenIndex: "1", Connector: "erc1155", - Identity: "0x0", + Key: "0x0", } operation.Amount.Int().SetInt64(10) @@ -183,7 +183,7 @@ func TestAddTokenAccountBalanceUpdateSuccess(t *testing.T) { operation := &fftypes.TokenBalanceChange{ PoolProtocolID: "F1", TokenIndex: "1", - Identity: "0x0", + Key: "0x0", } operation.Amount.Int().SetInt64(10) diff --git a/internal/events/tokens_transferred.go b/internal/events/tokens_transferred.go index e34ae4d36d..3a2377ba2b 100644 --- a/internal/events/tokens_transferred.go +++ b/internal/events/tokens_transferred.go @@ -123,19 +123,19 @@ func (em *eventManager) TokensTransferred(tk tokens.Plugin, transfer *fftypes.To } if transfer.Type != fftypes.TokenTransferTypeMint { - balance.Identity = transfer.From + balance.Key = transfer.From balance.Amount.Int().Neg(transfer.Amount.Int()) if err := em.database.AddTokenAccountBalance(ctx, balance); err != nil { - log.L(ctx).Errorf("Failed to update account '%s' for token transfer '%s': %s", balance.Identity, transfer.ProtocolID, err) + log.L(ctx).Errorf("Failed to update account '%s' for token transfer '%s': %s", balance.Key, transfer.ProtocolID, err) return err } } if transfer.Type != fftypes.TokenTransferTypeBurn { - balance.Identity = transfer.To + balance.Key = transfer.To balance.Amount.Int().Set(transfer.Amount.Int()) if err := em.database.AddTokenAccountBalance(ctx, balance); err != nil { - log.L(ctx).Errorf("Failed to update account '%s for token transfer '%s': %s", balance.Identity, transfer.ProtocolID, err) + log.L(ctx).Errorf("Failed to update account '%s for token transfer '%s': %s", balance.Key, transfer.ProtocolID, err) return err } } diff --git a/internal/events/tokens_transferred_test.go b/internal/events/tokens_transferred_test.go index 1ca2dc0987..36544f66ca 100644 --- a/internal/events/tokens_transferred_test.go +++ b/internal/events/tokens_transferred_test.go @@ -47,13 +47,13 @@ func TestTokensTransferredSucceedWithRetries(t *testing.T) { fromBalance := &fftypes.TokenBalanceChange{ PoolProtocolID: "F1", TokenIndex: "0", - Identity: "0x1", + Key: "0x1", } fromBalance.Amount.Int().SetInt64(-1) toBalance := &fftypes.TokenBalanceChange{ PoolProtocolID: "F1", TokenIndex: "0", - Identity: "0x2", + Key: "0x2", } toBalance.Amount.Int().SetInt64(1) pool := &fftypes.TokenPool{ @@ -179,13 +179,13 @@ func TestTokensTransferredWithMessage(t *testing.T) { fromBalance := &fftypes.TokenBalanceChange{ PoolProtocolID: "F1", TokenIndex: "0", - Identity: "0x1", + Key: "0x1", } fromBalance.Amount.Int().SetInt64(-1) toBalance := &fftypes.TokenBalanceChange{ PoolProtocolID: "F1", TokenIndex: "0", - Identity: "0x2", + Key: "0x2", } toBalance.Amount.Int().SetInt64(1) pool := &fftypes.TokenPool{ diff --git a/pkg/database/plugin.go b/pkg/database/plugin.go index a142bf1758..9f718e3e15 100644 --- a/pkg/database/plugin.go +++ b/pkg/database/plugin.go @@ -776,7 +776,7 @@ var TokenAccountQueryFactory = &queryFields{ "poolprotocolid": &StringField{}, "tokenindex": &StringField{}, "connector": &StringField{}, - "identity": &StringField{}, + "key": &StringField{}, "balance": &Int64Field{}, } diff --git a/pkg/fftypes/tokenaccount.go b/pkg/fftypes/tokenaccount.go index e0071cf320..7b7bd241a4 100644 --- a/pkg/fftypes/tokenaccount.go +++ b/pkg/fftypes/tokenaccount.go @@ -20,7 +20,7 @@ type TokenAccount struct { PoolProtocolID string `json:"poolProtocolId,omitempty"` TokenIndex string `json:"tokenIndex,omitempty"` Connector string `json:"connector,omitempty"` - Identity string `json:"identity,omitempty"` + Key string `json:"key,omitempty"` Balance BigInt `json:"balance"` } @@ -29,13 +29,13 @@ func TokenAccountIdentifier(protocolID, tokenIndex, identity string) string { } func (t *TokenAccount) Identifier() string { - return TokenAccountIdentifier(t.PoolProtocolID, t.TokenIndex, t.Identity) + return TokenAccountIdentifier(t.PoolProtocolID, t.TokenIndex, t.Key) } type TokenBalanceChange struct { PoolProtocolID string TokenIndex string Connector string - Identity string + Key string Amount BigInt } diff --git a/pkg/fftypes/tokenaccount_test.go b/pkg/fftypes/tokenaccount_test.go index 5328ce96fd..bf40fa5009 100644 --- a/pkg/fftypes/tokenaccount_test.go +++ b/pkg/fftypes/tokenaccount_test.go @@ -26,7 +26,7 @@ func TestTokenAccountIdentifier(t *testing.T) { account := &TokenAccount{ PoolProtocolID: "123", TokenIndex: "1", - Identity: "0x00", + Key: "0x00", } assert.Equal(t, "123:1:0x00", account.Identifier()) } diff --git a/test/e2e/e2e_test.go b/test/e2e/e2e_test.go index 4713c6d319..f2d715170d 100644 --- a/test/e2e/e2e_test.go +++ b/test/e2e/e2e_test.go @@ -130,8 +130,8 @@ func validateReceivedMessages(ts *testState, client *resty.Client, msgType fftyp } func validateAccountBalances(t *testing.T, client *resty.Client, poolName, tokenIndex string, balances map[string]int64) { - for identity, balance := range balances { - account := GetTokenAccount(t, client, poolName, tokenIndex, identity) + for key, balance := range balances { + account := GetTokenAccount(t, client, poolName, tokenIndex, key) assert.Equal(t, "erc1155", account.Connector) assert.Equal(t, balance, account.Balance.Int().Int64()) } diff --git a/test/e2e/restclient.go b/test/e2e/restclient.go index 1996caa675..3582123b2d 100644 --- a/test/e2e/restclient.go +++ b/test/e2e/restclient.go @@ -375,16 +375,16 @@ func GetTokenTransfers(t *testing.T, client *resty.Client, poolName string) (tra return transfers } -func GetTokenAccount(t *testing.T, client *resty.Client, poolName, tokenIndex, identity string) (account *fftypes.TokenAccount) { +func GetTokenAccount(t *testing.T, client *resty.Client, poolName, tokenIndex, key string) (account *fftypes.TokenAccount) { var accounts []*fftypes.TokenAccount path := fmt.Sprintf(urlTokenAccounts, poolName) resp, err := client.R(). SetQueryParam("tokenIndex", tokenIndex). - SetQueryParam("identity", identity). + SetQueryParam("key", key). SetResult(&accounts). Get(path) require.NoError(t, err) require.Equal(t, 200, resp.StatusCode(), "GET %s [%d]: %s", path, resp.StatusCode(), resp.String()) - require.Greater(t, len(accounts), 0) + require.Equal(t, len(accounts), 1) return accounts[0] } From 53d324c0ec7a344237937cebc59940231fcca7ca Mon Sep 17 00:00:00 2001 From: Andrew Richardson Date: Wed, 20 Oct 2021 13:48:24 -0400 Subject: [PATCH 3/4] Add "updated" column for token accounts Signed-off-by: Andrew Richardson --- .../000035_add_tokenaccount_updated.down.sql | 3 +++ .../postgres/000035_add_tokenaccount_updated.up.sql | 5 +++++ .../sqlite/000035_add_tokenaccount_updated.down.sql | 1 + .../sqlite/000035_add_tokenaccount_updated.up.sql | 2 ++ docs/swagger/swagger.yaml | 12 ++++++++++++ internal/database/sqlcommon/tokenaccount_sql.go | 4 ++++ internal/database/sqlcommon/tokenaccount_sql_test.go | 8 +++++++- pkg/database/plugin.go | 1 + pkg/fftypes/tokenaccount.go | 11 ++++++----- 9 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 db/migrations/postgres/000035_add_tokenaccount_updated.down.sql create mode 100644 db/migrations/postgres/000035_add_tokenaccount_updated.up.sql create mode 100644 db/migrations/sqlite/000035_add_tokenaccount_updated.down.sql create mode 100644 db/migrations/sqlite/000035_add_tokenaccount_updated.up.sql diff --git a/db/migrations/postgres/000035_add_tokenaccount_updated.down.sql b/db/migrations/postgres/000035_add_tokenaccount_updated.down.sql new file mode 100644 index 0000000000..2dd70c89db --- /dev/null +++ b/db/migrations/postgres/000035_add_tokenaccount_updated.down.sql @@ -0,0 +1,3 @@ +BEGIN; +ALTER TABLE tokenaccount DROP COLUMN updated; +COMMIT; diff --git a/db/migrations/postgres/000035_add_tokenaccount_updated.up.sql b/db/migrations/postgres/000035_add_tokenaccount_updated.up.sql new file mode 100644 index 0000000000..b73902bfaa --- /dev/null +++ b/db/migrations/postgres/000035_add_tokenaccount_updated.up.sql @@ -0,0 +1,5 @@ +BEGIN; +ALTER TABLE tokenaccount ADD COLUMN updated BIGINT; +UPDATE tokenaccount SET updated = 0; +ALTER TABLE tokenaccount ALTER COLUMN updated SET NOT NULL; +COMMIT; diff --git a/db/migrations/sqlite/000035_add_tokenaccount_updated.down.sql b/db/migrations/sqlite/000035_add_tokenaccount_updated.down.sql new file mode 100644 index 0000000000..b32c3b18ad --- /dev/null +++ b/db/migrations/sqlite/000035_add_tokenaccount_updated.down.sql @@ -0,0 +1 @@ +ALTER TABLE tokenaccount DROP COLUMN updated; diff --git a/db/migrations/sqlite/000035_add_tokenaccount_updated.up.sql b/db/migrations/sqlite/000035_add_tokenaccount_updated.up.sql new file mode 100644 index 0000000000..8a609736f3 --- /dev/null +++ b/db/migrations/sqlite/000035_add_tokenaccount_updated.up.sql @@ -0,0 +1,2 @@ +ALTER TABLE tokenaccount ADD COLUMN updated BIGINT; +UPDATE tokenaccount SET updated = 0; diff --git a/docs/swagger/swagger.yaml b/docs/swagger/swagger.yaml index 5018f09420..d527516ab6 100644 --- a/docs/swagger/swagger.yaml +++ b/docs/swagger/swagger.yaml @@ -4653,6 +4653,11 @@ paths: name: tokenindex schema: type: string + - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^' + in: query + name: updated + schema: + type: string - description: Sort field. For multi-field sort use comma separated values (or multiple query values) with '-' prefix for descending in: query @@ -4703,6 +4708,7 @@ paths: type: string tokenIndex: type: string + updated: {} type: object type: array description: Success @@ -5593,6 +5599,11 @@ paths: name: tokenindex schema: type: string + - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^' + in: query + name: updated + schema: + type: string - description: Sort field. For multi-field sort use comma separated values (or multiple query values) with '-' prefix for descending in: query @@ -5643,6 +5654,7 @@ paths: type: string tokenIndex: type: string + updated: {} type: object type: array description: Success diff --git a/internal/database/sqlcommon/tokenaccount_sql.go b/internal/database/sqlcommon/tokenaccount_sql.go index 13cb041009..796288a35d 100644 --- a/internal/database/sqlcommon/tokenaccount_sql.go +++ b/internal/database/sqlcommon/tokenaccount_sql.go @@ -34,6 +34,7 @@ var ( "connector", "key", "balance", + "updated", } tokenAccountFilterFieldMap = map[string]string{ "poolprotocolid": "pool_protocol_id", @@ -75,6 +76,7 @@ func (s *SQLCommon) AddTokenAccountBalance(ctx context.Context, account *fftypes if err = s.updateTx(ctx, tx, sq.Update("tokenaccount"). Set("balance", balance). + Set("updated", fftypes.Now()). Where(sq.And{ sq.Eq{"pool_protocol_id": account.PoolProtocolID}, sq.Eq{"token_index": account.TokenIndex}, @@ -94,6 +96,7 @@ func (s *SQLCommon) AddTokenAccountBalance(ctx context.Context, account *fftypes account.Connector, account.Key, account.Amount, + fftypes.Now(), ), nil, ); err != nil { @@ -112,6 +115,7 @@ func (s *SQLCommon) tokenAccountResult(ctx context.Context, row *sql.Rows) (*fft &account.Connector, &account.Key, &account.Balance, + &account.Updated, ) if err != nil { return nil, i18n.WrapError(ctx, err, i18n.MsgDBReadErr, "tokenaccount") diff --git a/internal/database/sqlcommon/tokenaccount_sql_test.go b/internal/database/sqlcommon/tokenaccount_sql_test.go index 271ada9619..6909e0b34b 100644 --- a/internal/database/sqlcommon/tokenaccount_sql_test.go +++ b/internal/database/sqlcommon/tokenaccount_sql_test.go @@ -59,6 +59,8 @@ func TestTokenAccountE2EWithDB(t *testing.T) { accountRead, err := s.GetTokenAccount(ctx, "F1", "1", "0x0") assert.NoError(t, err) assert.NotNil(t, accountRead) + assert.Greater(t, accountRead.Updated.UnixNano(), int64(0)) + accountRead.Updated = nil accountReadJson, _ := json.Marshal(&accountRead) assert.Equal(t, string(accountJson), string(accountReadJson)) @@ -73,6 +75,8 @@ func TestTokenAccountE2EWithDB(t *testing.T) { assert.NoError(t, err) assert.Equal(t, 1, len(accounts)) assert.Equal(t, int64(1), *res.TotalCount) + assert.Greater(t, accounts[0].Updated.UnixNano(), int64(0)) + accounts[0].Updated = nil accountReadJson, _ = json.Marshal(accounts[0]) assert.Equal(t, string(accountJson), string(accountReadJson)) @@ -84,6 +88,8 @@ func TestTokenAccountE2EWithDB(t *testing.T) { accountRead, err = s.GetTokenAccount(ctx, "F1", "1", "0x0") assert.NoError(t, err) assert.NotNil(t, accountRead) + assert.Greater(t, accountRead.Updated.UnixNano(), int64(0)) + accountRead.Updated = nil accountReadJson, _ = json.Marshal(&accountRead) account.Balance.Int().SetInt64(20) accountJson, _ = json.Marshal(&account) @@ -168,7 +174,7 @@ func TestAddTokenAccountBalanceInsertSuccess(t *testing.T) { db.ExpectBegin() db.ExpectQuery("SELECT .*").WillReturnRows(sqlmock.NewRows([]string{"id"})) db.ExpectExec("INSERT .*"). - WithArgs("F1", "1", "erc1155", "0x0", sqlmock.AnyArg()). + WithArgs("F1", "1", "erc1155", "0x0", sqlmock.AnyArg(), sqlmock.AnyArg()). WillReturnResult(sqlmock.NewResult(1, 1)) db.ExpectCommit() err := s.AddTokenAccountBalance(context.Background(), operation) diff --git a/pkg/database/plugin.go b/pkg/database/plugin.go index 9f718e3e15..bd21b7875b 100644 --- a/pkg/database/plugin.go +++ b/pkg/database/plugin.go @@ -778,6 +778,7 @@ var TokenAccountQueryFactory = &queryFields{ "connector": &StringField{}, "key": &StringField{}, "balance": &Int64Field{}, + "updated": &TimeField{}, } // TokenTransferQueryFactory filter fields for token transfers diff --git a/pkg/fftypes/tokenaccount.go b/pkg/fftypes/tokenaccount.go index 7b7bd241a4..9174ceffdd 100644 --- a/pkg/fftypes/tokenaccount.go +++ b/pkg/fftypes/tokenaccount.go @@ -17,11 +17,12 @@ package fftypes type TokenAccount struct { - PoolProtocolID string `json:"poolProtocolId,omitempty"` - TokenIndex string `json:"tokenIndex,omitempty"` - Connector string `json:"connector,omitempty"` - Key string `json:"key,omitempty"` - Balance BigInt `json:"balance"` + PoolProtocolID string `json:"poolProtocolId,omitempty"` + TokenIndex string `json:"tokenIndex,omitempty"` + Connector string `json:"connector,omitempty"` + Key string `json:"key,omitempty"` + Balance BigInt `json:"balance"` + Updated *FFTime `json:"updated,omitempty"` } func TokenAccountIdentifier(protocolID, tokenIndex, identity string) string { From 55beb52950294d75cf978d7f2f4cf4b30bb2ae53 Mon Sep 17 00:00:00 2001 From: Andrew Richardson Date: Wed, 20 Oct 2021 13:57:53 -0400 Subject: [PATCH 4/4] Add "standard" column for token pools Placeholder where a plugin can (optionally) return a well-defined standard label for a pool, such as "ERC1155". Usage is up to the plugin. Signed-off-by: Andrew Richardson --- .../000036_add_tokenpool_standard.down.sql | 3 +++ .../000036_add_tokenpool_standard.up.sql | 3 +++ .../000036_add_tokenpool_standard.down.sql | 1 + .../000036_add_tokenpool_standard.up.sql | 1 + docs/swagger/swagger.yaml | 20 +++++++++++++++++++ internal/apiserver/route_post_token_pool.go | 2 +- internal/database/sqlcommon/tokenpool_sql.go | 4 ++++ .../database/sqlcommon/tokenpool_sql_test.go | 1 + internal/tokens/fftokens/fftokens.go | 2 ++ pkg/database/plugin.go | 1 + pkg/fftypes/tokenpool.go | 1 + 11 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 db/migrations/postgres/000036_add_tokenpool_standard.down.sql create mode 100644 db/migrations/postgres/000036_add_tokenpool_standard.up.sql create mode 100644 db/migrations/sqlite/000036_add_tokenpool_standard.down.sql create mode 100644 db/migrations/sqlite/000036_add_tokenpool_standard.up.sql diff --git a/db/migrations/postgres/000036_add_tokenpool_standard.down.sql b/db/migrations/postgres/000036_add_tokenpool_standard.down.sql new file mode 100644 index 0000000000..790ccb46d5 --- /dev/null +++ b/db/migrations/postgres/000036_add_tokenpool_standard.down.sql @@ -0,0 +1,3 @@ +BEGIN; +ALTER TABLE tokenpool DROP COLUMN standard; +COMMIT; diff --git a/db/migrations/postgres/000036_add_tokenpool_standard.up.sql b/db/migrations/postgres/000036_add_tokenpool_standard.up.sql new file mode 100644 index 0000000000..ed231a68e8 --- /dev/null +++ b/db/migrations/postgres/000036_add_tokenpool_standard.up.sql @@ -0,0 +1,3 @@ +BEGIN; +ALTER TABLE tokenpool ADD COLUMN standard VARCHAR(64); +COMMIT; diff --git a/db/migrations/sqlite/000036_add_tokenpool_standard.down.sql b/db/migrations/sqlite/000036_add_tokenpool_standard.down.sql new file mode 100644 index 0000000000..e268a49ee1 --- /dev/null +++ b/db/migrations/sqlite/000036_add_tokenpool_standard.down.sql @@ -0,0 +1 @@ +ALTER TABLE tokenpool DROP COLUMN standard; diff --git a/db/migrations/sqlite/000036_add_tokenpool_standard.up.sql b/db/migrations/sqlite/000036_add_tokenpool_standard.up.sql new file mode 100644 index 0000000000..b0226f5e17 --- /dev/null +++ b/db/migrations/sqlite/000036_add_tokenpool_standard.up.sql @@ -0,0 +1 @@ +ALTER TABLE tokenpool ADD COLUMN standard VARCHAR(64); diff --git a/docs/swagger/swagger.yaml b/docs/swagger/swagger.yaml index d527516ab6..760a09548f 100644 --- a/docs/swagger/swagger.yaml +++ b/docs/swagger/swagger.yaml @@ -4330,6 +4330,11 @@ paths: name: protocolid schema: type: string + - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^' + in: query + name: standard + schema: + type: string - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^' in: query name: symbol @@ -4397,6 +4402,8 @@ paths: type: string protocolId: type: string + standard: + type: string symbol: type: string tx: @@ -4483,6 +4490,8 @@ paths: type: string protocolId: type: string + standard: + type: string symbol: type: string tx: @@ -4516,6 +4525,8 @@ paths: type: string protocolId: type: string + standard: + type: string symbol: type: string tx: @@ -4583,6 +4594,8 @@ paths: type: string protocolId: type: string + standard: + type: string symbol: type: string tx: @@ -5747,6 +5760,11 @@ paths: name: protocolid schema: type: string + - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^' + in: query + name: standard + schema: + type: string - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^' in: query name: symbol @@ -5814,6 +5832,8 @@ paths: type: string protocolId: type: string + standard: + type: string symbol: type: string tx: diff --git a/internal/apiserver/route_post_token_pool.go b/internal/apiserver/route_post_token_pool.go index eef994a7f2..e92c87eb65 100644 --- a/internal/apiserver/route_post_token_pool.go +++ b/internal/apiserver/route_post_token_pool.go @@ -40,7 +40,7 @@ var postTokenPool = &oapispec.Route{ FilterFactory: nil, Description: i18n.MsgTBD, JSONInputValue: func() interface{} { return &fftypes.TokenPool{} }, - JSONInputMask: []string{"ID", "Namespace", "ProtocolID", "TX", "Connector", "Message", "Created"}, + JSONInputMask: []string{"ID", "Namespace", "Standard", "ProtocolID", "TX", "Connector", "Message", "Created"}, JSONOutputValue: func() interface{} { return &fftypes.TokenPool{} }, JSONOutputCodes: []int{http.StatusAccepted, http.StatusOK}, JSONHandler: func(r *oapispec.APIRequest) (output interface{}, err error) { diff --git a/internal/database/sqlcommon/tokenpool_sql.go b/internal/database/sqlcommon/tokenpool_sql.go index ff1da36aaf..f2a0a25c92 100644 --- a/internal/database/sqlcommon/tokenpool_sql.go +++ b/internal/database/sqlcommon/tokenpool_sql.go @@ -32,6 +32,7 @@ var ( "id", "namespace", "name", + "standard", "protocol_id", "type", "connector", @@ -83,6 +84,7 @@ func (s *SQLCommon) UpsertTokenPool(ctx context.Context, pool *fftypes.TokenPool sq.Update("tokenpool"). Set("namespace", pool.Namespace). Set("name", pool.Name). + Set("standard", pool.Standard). Set("protocol_id", pool.ProtocolID). Set("type", pool.Type). Set("connector", pool.Connector). @@ -107,6 +109,7 @@ func (s *SQLCommon) UpsertTokenPool(ctx context.Context, pool *fftypes.TokenPool pool.ID, pool.Namespace, pool.Name, + pool.Standard, pool.ProtocolID, pool.Type, pool.Connector, @@ -134,6 +137,7 @@ func (s *SQLCommon) tokenPoolResult(ctx context.Context, row *sql.Rows) (*fftype &pool.ID, &pool.Namespace, &pool.Name, + &pool.Standard, &pool.ProtocolID, &pool.Type, &pool.Connector, diff --git a/internal/database/sqlcommon/tokenpool_sql_test.go b/internal/database/sqlcommon/tokenpool_sql_test.go index 61040847db..82c41e5d8b 100644 --- a/internal/database/sqlcommon/tokenpool_sql_test.go +++ b/internal/database/sqlcommon/tokenpool_sql_test.go @@ -41,6 +41,7 @@ func TestTokenPoolE2EWithDB(t *testing.T) { ID: poolID, Namespace: "ns1", Name: "my-pool", + Standard: "ERC1155", Type: fftypes.TokenTypeFungible, ProtocolID: "12345", Connector: "erc1155", diff --git a/internal/tokens/fftokens/fftokens.go b/internal/tokens/fftokens/fftokens.go index 6d11a4be44..8ff6f37bd8 100644 --- a/internal/tokens/fftokens/fftokens.go +++ b/internal/tokens/fftokens/fftokens.go @@ -157,6 +157,7 @@ func (ft *FFTokens) handleReceipt(ctx context.Context, data fftypes.JSONObject) func (ft *FFTokens) handleTokenPoolCreate(ctx context.Context, data fftypes.JSONObject) (err error) { tokenType := data.GetString("type") protocolID := data.GetString("poolId") + standard := data.GetString("standard") // this is optional trackingID := data.GetString("trackingId") operatorAddress := data.GetString("operator") tx := data.GetObject("transaction") @@ -180,6 +181,7 @@ func (ft *FFTokens) handleTokenPoolCreate(ctx context.Context, data fftypes.JSON pool := &fftypes.TokenPool{ Type: fftypes.FFEnum(tokenType), ProtocolID: protocolID, + Standard: standard, Connector: ft.configuredName, Key: operatorAddress, TX: fftypes.TransactionRef{ diff --git a/pkg/database/plugin.go b/pkg/database/plugin.go index bd21b7875b..689c25fa65 100644 --- a/pkg/database/plugin.go +++ b/pkg/database/plugin.go @@ -764,6 +764,7 @@ var TokenPoolQueryFactory = &queryFields{ "type": &StringField{}, "namespace": &StringField{}, "name": &StringField{}, + "standard": &StringField{}, "protocolid": &StringField{}, "key": &StringField{}, "symbol": &StringField{}, diff --git a/pkg/fftypes/tokenpool.go b/pkg/fftypes/tokenpool.go index c41d4a46a4..20137abbc8 100644 --- a/pkg/fftypes/tokenpool.go +++ b/pkg/fftypes/tokenpool.go @@ -32,6 +32,7 @@ type TokenPool struct { Type TokenType `json:"type" ffenum:"tokentype"` Namespace string `json:"namespace,omitempty"` Name string `json:"name,omitempty"` + Standard string `json:"standard,omitempty"` ProtocolID string `json:"protocolId,omitempty"` Key string `json:"key,omitempty"` Symbol string `json:"symbol,omitempty"`