diff --git a/db/migrations/postgres/000037_add_token_namespace_fields.down.sql b/db/migrations/postgres/000037_add_token_namespace_fields.down.sql new file mode 100644 index 0000000000..3f2fcbfa4c --- /dev/null +++ b/db/migrations/postgres/000037_add_token_namespace_fields.down.sql @@ -0,0 +1,4 @@ +BEGIN; +ALTER TABLE tokenaccount DROP COLUMN namespace; +ALTER TABLE tokentransfer DROP COLUMN namespace; +COMMIT; diff --git a/db/migrations/postgres/000037_add_token_namespace_fields.up.sql b/db/migrations/postgres/000037_add_token_namespace_fields.up.sql new file mode 100644 index 0000000000..bee0999a80 --- /dev/null +++ b/db/migrations/postgres/000037_add_token_namespace_fields.up.sql @@ -0,0 +1,13 @@ +BEGIN; +ALTER TABLE tokenaccount ADD COLUMN namespace VARCHAR(64); +ALTER TABLE tokentransfer ADD COLUMN namespace VARCHAR(64); + +UPDATE tokenaccount SET namespace = pool.namespace + FROM (SELECT protocol_id, namespace FROM tokenpool) AS pool + WHERE tokenaccount.pool_protocol_id = pool.protocol_id; + +UPDATE tokentransfer SET namespace = pool.namespace + FROM (SELECT protocol_id, namespace FROM tokenpool) AS pool + WHERE tokentransfer.pool_protocol_id = pool.protocol_id; + +COMMIT; diff --git a/db/migrations/sqlite/000033_add_token_connector_fields.up.sql b/db/migrations/sqlite/000033_add_token_connector_fields.up.sql index c2b5349af0..ed8ab7437a 100644 --- a/db/migrations/sqlite/000033_add_token_connector_fields.up.sql +++ b/db/migrations/sqlite/000033_add_token_connector_fields.up.sql @@ -1,4 +1,3 @@ -DELETE FROM tokenaccount; ALTER TABLE tokenaccount ADD COLUMN connector VARCHAR(64); ALTER TABLE tokentransfer ADD COLUMN connector VARCHAR(64); diff --git a/db/migrations/sqlite/000037_add_token_namespace_fields.down.sql b/db/migrations/sqlite/000037_add_token_namespace_fields.down.sql new file mode 100644 index 0000000000..cc4842d578 --- /dev/null +++ b/db/migrations/sqlite/000037_add_token_namespace_fields.down.sql @@ -0,0 +1,2 @@ +ALTER TABLE tokenaccount DROP COLUMN namespace; +ALTER TABLE tokentransfer DROP COLUMN namespace; diff --git a/db/migrations/sqlite/000037_add_token_namespace_fields.up.sql b/db/migrations/sqlite/000037_add_token_namespace_fields.up.sql new file mode 100644 index 0000000000..f0e452220e --- /dev/null +++ b/db/migrations/sqlite/000037_add_token_namespace_fields.up.sql @@ -0,0 +1,10 @@ +ALTER TABLE tokenaccount ADD COLUMN namespace VARCHAR(64); +ALTER TABLE tokentransfer ADD COLUMN namespace VARCHAR(64); + +UPDATE tokenaccount SET namespace = pool.namespace + FROM (SELECT protocol_id, namespace FROM tokenpool) AS pool + WHERE tokenaccount.pool_protocol_id = pool.protocol_id; + +UPDATE tokentransfer SET namespace = pool.namespace + FROM (SELECT protocol_id, namespace 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 477fd7472c..cf094abe31 100644 --- a/docs/swagger/swagger.yaml +++ b/docs/swagger/swagger.yaml @@ -4661,6 +4661,11 @@ paths: name: key schema: type: string + - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^' + in: query + name: namespace + schema: + type: string - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^' in: query name: poolprotocolid @@ -4722,6 +4727,8 @@ paths: type: string key: type: string + namespace: + type: string poolProtocolId: type: string tokenIndex: @@ -4870,6 +4877,8 @@ paths: type: boolean type: object messageHash: {} + namespace: + type: string poolProtocolId: type: string protocolId: @@ -4907,6 +4916,8 @@ paths: type: string localId: {} messageHash: {} + namespace: + type: string poolProtocolId: type: string protocolId: @@ -4940,6 +4951,8 @@ paths: type: string localId: {} messageHash: {} + namespace: + type: string poolProtocolId: type: string protocolId: @@ -5098,6 +5111,8 @@ paths: type: boolean type: object messageHash: {} + namespace: + type: string poolProtocolId: type: string protocolId: @@ -5135,6 +5150,8 @@ paths: type: string localId: {} messageHash: {} + namespace: + type: string poolProtocolId: type: string protocolId: @@ -5168,6 +5185,8 @@ paths: type: string localId: {} messageHash: {} + namespace: + type: string poolProtocolId: type: string protocolId: @@ -5254,6 +5273,11 @@ paths: name: messagehash schema: type: string + - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^' + in: query + name: namespace + schema: + type: string - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^' in: query name: poolprotocolid @@ -5325,6 +5349,8 @@ paths: type: string localId: {} messageHash: {} + namespace: + type: string poolProtocolId: type: string protocolId: @@ -5483,6 +5509,8 @@ paths: type: boolean type: object messageHash: {} + namespace: + type: string poolProtocolId: type: string protocolId: @@ -5520,6 +5548,8 @@ paths: type: string localId: {} messageHash: {} + namespace: + type: string poolProtocolId: type: string protocolId: @@ -5553,6 +5583,8 @@ paths: type: string localId: {} messageHash: {} + namespace: + type: string poolProtocolId: type: string protocolId: @@ -5607,6 +5639,11 @@ paths: name: key schema: type: string + - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^' + in: query + name: namespace + schema: + type: string - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^' in: query name: poolprotocolid @@ -5668,6 +5705,8 @@ paths: type: string key: type: string + namespace: + type: string poolProtocolId: type: string tokenIndex: @@ -5976,6 +6015,11 @@ paths: name: messagehash schema: type: string + - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^' + in: query + name: namespace + schema: + type: string - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^' in: query name: poolprotocolid @@ -6047,6 +6091,8 @@ paths: type: string localId: {} messageHash: {} + namespace: + type: string poolProtocolId: type: string protocolId: @@ -6109,6 +6155,8 @@ paths: type: string localId: {} messageHash: {} + namespace: + type: string poolProtocolId: type: string protocolId: diff --git a/internal/apiserver/route_post_token_transfer.go b/internal/apiserver/route_post_token_transfer.go index c36ef24542..0d70356818 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", "Connector", "TX", "Created"}, + JSONInputMask: []string{"Type", "LocalID", "PoolProtocolID", "ProtocolID", "MessageHash", "Connector", "Namespace", "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 d4afaf71a5..8750aa3ccb 100644 --- a/internal/assets/manager.go +++ b/internal/assets/manager.go @@ -109,7 +109,7 @@ func (am *assetManager) scopeNS(ns string, filter database.AndFilter) database.A } func (am *assetManager) GetTokenAccounts(ctx context.Context, ns string, filter database.AndFilter) ([]*fftypes.TokenAccount, *database.FilterResult, error) { - return am.database.GetTokenAccounts(ctx, filter) + return am.database.GetTokenAccounts(ctx, am.scopeNS(ns, filter)) } func (am *assetManager) GetTokenAccountsByPool(ctx context.Context, ns, connector, poolName string, filter database.AndFilter) ([]*fftypes.TokenAccount, *database.FilterResult, error) { diff --git a/internal/assets/token_transfer.go b/internal/assets/token_transfer.go index 332530e64b..c68d0c4043 100644 --- a/internal/assets/token_transfer.go +++ b/internal/assets/token_transfer.go @@ -34,7 +34,7 @@ func addTokenTransferInputs(op *fftypes.Operation, transfer *fftypes.TokenTransf } func (am *assetManager) GetTokenTransfers(ctx context.Context, ns string, filter database.AndFilter) ([]*fftypes.TokenTransfer, *database.FilterResult, error) { - return am.database.GetTokenTransfers(ctx, filter) + return am.database.GetTokenTransfers(ctx, am.scopeNS(ns, filter)) } func (am *assetManager) GetTokenTransferByID(ctx context.Context, ns, id string) (*fftypes.TokenTransfer, error) { diff --git a/internal/database/sqlcommon/tokenaccount_sql.go b/internal/database/sqlcommon/tokenaccount_sql.go index 796288a35d..372629e4bd 100644 --- a/internal/database/sqlcommon/tokenaccount_sql.go +++ b/internal/database/sqlcommon/tokenaccount_sql.go @@ -32,6 +32,7 @@ var ( "pool_protocol_id", "token_index", "connector", + "namespace", "key", "balance", "updated", @@ -94,6 +95,7 @@ func (s *SQLCommon) AddTokenAccountBalance(ctx context.Context, account *fftypes account.PoolProtocolID, account.TokenIndex, account.Connector, + account.Namespace, account.Key, account.Amount, fftypes.Now(), @@ -113,6 +115,7 @@ func (s *SQLCommon) tokenAccountResult(ctx context.Context, row *sql.Rows) (*fft &account.PoolProtocolID, &account.TokenIndex, &account.Connector, + &account.Namespace, &account.Key, &account.Balance, &account.Updated, diff --git a/internal/database/sqlcommon/tokenaccount_sql_test.go b/internal/database/sqlcommon/tokenaccount_sql_test.go index 6909e0b34b..e348237408 100644 --- a/internal/database/sqlcommon/tokenaccount_sql_test.go +++ b/internal/database/sqlcommon/tokenaccount_sql_test.go @@ -40,6 +40,7 @@ func TestTokenAccountE2EWithDB(t *testing.T) { PoolProtocolID: "F1", TokenIndex: "1", Connector: "erc1155", + Namespace: "ns1", Key: "0x0", } operation.Amount.Int().SetInt64(10) @@ -47,6 +48,7 @@ func TestTokenAccountE2EWithDB(t *testing.T) { PoolProtocolID: "F1", TokenIndex: "1", Connector: "erc1155", + Namespace: "ns1", Key: "0x0", } account.Balance.Int().SetInt64(10) @@ -167,6 +169,7 @@ func TestAddTokenAccountBalanceInsertSuccess(t *testing.T) { PoolProtocolID: "F1", TokenIndex: "1", Connector: "erc1155", + Namespace: "ns1", Key: "0x0", } operation.Amount.Int().SetInt64(10) @@ -174,7 +177,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(), sqlmock.AnyArg()). + WithArgs("F1", "1", "erc1155", "ns1", "0x0", sqlmock.AnyArg(), 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 ffc1e5bf35..67eb5fd47e 100644 --- a/internal/database/sqlcommon/tokentransfer_sql.go +++ b/internal/database/sqlcommon/tokentransfer_sql.go @@ -34,6 +34,7 @@ var ( "pool_protocol_id", "token_index", "connector", + "namespace", "key", "from_key", "to_key", @@ -83,6 +84,7 @@ func (s *SQLCommon) UpsertTokenTransfer(ctx context.Context, transfer *fftypes.T Set("pool_protocol_id", transfer.PoolProtocolID). Set("token_index", transfer.TokenIndex). Set("connector", transfer.Connector). + Set("namespace", transfer.Namespace). Set("key", transfer.Key). Set("from_key", transfer.From). Set("to_key", transfer.To). @@ -108,6 +110,7 @@ func (s *SQLCommon) UpsertTokenTransfer(ctx context.Context, transfer *fftypes.T transfer.PoolProtocolID, transfer.TokenIndex, transfer.Connector, + transfer.Namespace, transfer.Key, transfer.From, transfer.To, @@ -137,6 +140,7 @@ func (s *SQLCommon) tokenTransferResult(ctx context.Context, row *sql.Rows) (*ff &transfer.PoolProtocolID, &transfer.TokenIndex, &transfer.Connector, + &transfer.Namespace, &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 93c70f5b2d..c6d872f2b0 100644 --- a/internal/database/sqlcommon/tokentransfer_sql_test.go +++ b/internal/database/sqlcommon/tokentransfer_sql_test.go @@ -41,6 +41,7 @@ func TestTokenTransferE2EWithDB(t *testing.T) { PoolProtocolID: "F1", TokenIndex: "1", Connector: "erc1155", + Namespace: "ns1", From: "0x01", To: "0x02", ProtocolID: "12345", diff --git a/internal/events/tokens_transferred.go b/internal/events/tokens_transferred.go index 3a2377ba2b..0008e5bfbf 100644 --- a/internal/events/tokens_transferred.go +++ b/internal/events/tokens_transferred.go @@ -102,6 +102,7 @@ func (em *eventManager) TokensTransferred(tk tokens.Plugin, transfer *fftypes.To log.L(ctx).Warnf("Token transfer received for unknown pool '%s' - ignoring: %s", transfer.PoolProtocolID, protocolTxID) return nil } + transfer.Namespace = pool.Namespace if transfer.TX.ID != nil { if valid, err := em.persistTokenTransaction(ctx, pool.Namespace, transfer, protocolTxID, additionalInfo); err != nil || !valid { @@ -120,6 +121,7 @@ func (em *eventManager) TokensTransferred(tk tokens.Plugin, transfer *fftypes.To PoolProtocolID: transfer.PoolProtocolID, TokenIndex: transfer.TokenIndex, Connector: transfer.Connector, + Namespace: transfer.Namespace, } if transfer.Type != fftypes.TokenTransferTypeMint { diff --git a/internal/events/tokens_transferred_test.go b/internal/events/tokens_transferred_test.go index 36544f66ca..a952a42ed2 100644 --- a/internal/events/tokens_transferred_test.go +++ b/internal/events/tokens_transferred_test.go @@ -39,6 +39,7 @@ func TestTokensTransferredSucceedWithRetries(t *testing.T) { Type: fftypes.TokenTransferTypeTransfer, PoolProtocolID: "F1", TokenIndex: "0", + Connector: "erc1155", Key: "0x12345", From: "0x1", To: "0x2", @@ -47,12 +48,16 @@ func TestTokensTransferredSucceedWithRetries(t *testing.T) { fromBalance := &fftypes.TokenBalanceChange{ PoolProtocolID: "F1", TokenIndex: "0", + Connector: "erc1155", + Namespace: "ns1", Key: "0x1", } fromBalance.Amount.Int().SetInt64(-1) toBalance := &fftypes.TokenBalanceChange{ PoolProtocolID: "F1", TokenIndex: "0", + Connector: "erc1155", + Namespace: "ns1", Key: "0x2", } toBalance.Amount.Int().SetInt64(1) @@ -170,6 +175,7 @@ func TestTokensTransferredWithMessage(t *testing.T) { Type: fftypes.TokenTransferTypeTransfer, PoolProtocolID: "F1", TokenIndex: "0", + Connector: "erc1155", Key: "0x12345", From: "0x1", To: "0x2", @@ -179,12 +185,16 @@ func TestTokensTransferredWithMessage(t *testing.T) { fromBalance := &fftypes.TokenBalanceChange{ PoolProtocolID: "F1", TokenIndex: "0", + Connector: "erc1155", + Namespace: "ns1", Key: "0x1", } fromBalance.Amount.Int().SetInt64(-1) toBalance := &fftypes.TokenBalanceChange{ PoolProtocolID: "F1", TokenIndex: "0", + Connector: "erc1155", + Namespace: "ns1", Key: "0x2", } toBalance.Amount.Int().SetInt64(1) diff --git a/pkg/database/plugin.go b/pkg/database/plugin.go index d3e6eef9fd..45c82c1229 100644 --- a/pkg/database/plugin.go +++ b/pkg/database/plugin.go @@ -778,6 +778,7 @@ var TokenAccountQueryFactory = &queryFields{ "poolprotocolid": &StringField{}, "tokenindex": &StringField{}, "connector": &StringField{}, + "namespace": &StringField{}, "key": &StringField{}, "balance": &Int64Field{}, "updated": &TimeField{}, @@ -789,6 +790,7 @@ var TokenTransferQueryFactory = &queryFields{ "poolprotocolid": &StringField{}, "tokenindex": &StringField{}, "connector": &StringField{}, + "namespace": &StringField{}, "key": &StringField{}, "from": &StringField{}, "to": &StringField{}, diff --git a/pkg/fftypes/tokenaccount.go b/pkg/fftypes/tokenaccount.go index 9174ceffdd..1857fc5805 100644 --- a/pkg/fftypes/tokenaccount.go +++ b/pkg/fftypes/tokenaccount.go @@ -20,6 +20,7 @@ type TokenAccount struct { PoolProtocolID string `json:"poolProtocolId,omitempty"` TokenIndex string `json:"tokenIndex,omitempty"` Connector string `json:"connector,omitempty"` + Namespace string `json:"namespace,omitempty"` Key string `json:"key,omitempty"` Balance BigInt `json:"balance"` Updated *FFTime `json:"updated,omitempty"` @@ -37,6 +38,7 @@ type TokenBalanceChange struct { PoolProtocolID string TokenIndex string Connector string + Namespace string Key string Amount BigInt } diff --git a/pkg/fftypes/tokentransfer.go b/pkg/fftypes/tokentransfer.go index 47e2c437b9..d23829b12f 100644 --- a/pkg/fftypes/tokentransfer.go +++ b/pkg/fftypes/tokentransfer.go @@ -30,6 +30,7 @@ type TokenTransfer struct { PoolProtocolID string `json:"poolProtocolId,omitempty"` TokenIndex string `json:"tokenIndex,omitempty"` Connector string `json:"connector,omitempty"` + Namespace string `json:"namespace,omitempty"` Key string `json:"key,omitempty"` From string `json:"from,omitempty"` To string `json:"to,omitempty"`