diff --git a/db/migrations/postgres/000057_add_tokentransfer_blockchainevent.down.sql b/db/migrations/postgres/000057_add_tokentransfer_blockchainevent.down.sql index 0cf0f00dc2..62335086f2 100644 --- a/db/migrations/postgres/000057_add_tokentransfer_blockchainevent.down.sql +++ b/db/migrations/postgres/000057_add_tokentransfer_blockchainevent.down.sql @@ -1,5 +1,3 @@ BEGIN; ALTER TABLE tokentransfer DROP COLUMN blockchain_event; -ALTER TABLE tokentransfer ADD COLUMN tx_type VARCHAR(64); -ALTER TABLE tokentransfer ADD COLUMN tx_id UUID; COMMIT; diff --git a/db/migrations/postgres/000057_add_tokentransfer_blockchainevent.up.sql b/db/migrations/postgres/000057_add_tokentransfer_blockchainevent.up.sql index ea5dbb419c..e6feeb05bf 100644 --- a/db/migrations/postgres/000057_add_tokentransfer_blockchainevent.up.sql +++ b/db/migrations/postgres/000057_add_tokentransfer_blockchainevent.up.sql @@ -1,5 +1,3 @@ BEGIN; -ALTER TABLE tokentransfer DROP COLUMN tx_type; -ALTER TABLE tokentransfer DROP COLUMN tx_id; ALTER TABLE tokentransfer ADD COLUMN blockchain_event UUID; COMMIT; diff --git a/db/migrations/sqlite/000057_add_tokentransfer_blockchainevent.down.sql b/db/migrations/sqlite/000057_add_tokentransfer_blockchainevent.down.sql index 922f2c7a6d..58e8e4c1e5 100644 --- a/db/migrations/sqlite/000057_add_tokentransfer_blockchainevent.down.sql +++ b/db/migrations/sqlite/000057_add_tokentransfer_blockchainevent.down.sql @@ -1,3 +1 @@ ALTER TABLE tokentransfer DROP COLUMN blockchain_event; -ALTER TABLE tokentransfer ADD COLUMN tx_type VARCHAR(64); -ALTER TABLE tokentransfer ADD COLUMN tx_id UUID; diff --git a/db/migrations/sqlite/000057_add_tokentransfer_blockchainevent.up.sql b/db/migrations/sqlite/000057_add_tokentransfer_blockchainevent.up.sql index acf28ccf3b..f109fb2433 100644 --- a/db/migrations/sqlite/000057_add_tokentransfer_blockchainevent.up.sql +++ b/db/migrations/sqlite/000057_add_tokentransfer_blockchainevent.up.sql @@ -1,3 +1 @@ -ALTER TABLE tokentransfer DROP COLUMN tx_type; -ALTER TABLE tokentransfer DROP COLUMN tx_id; ALTER TABLE tokentransfer ADD COLUMN blockchain_event UUID; diff --git a/docs/swagger/swagger.yaml b/docs/swagger/swagger.yaml index 65361c6765..6ed524ea63 100644 --- a/docs/swagger/swagger.yaml +++ b/docs/swagger/swagger.yaml @@ -7439,6 +7439,12 @@ paths: type: string tokenIndex: type: string + tx: + properties: + id: {} + type: + type: string + type: object type: enum: - mint @@ -7475,6 +7481,12 @@ paths: type: string tokenIndex: type: string + tx: + properties: + id: {} + type: + type: string + type: object type: enum: - mint @@ -7511,6 +7523,12 @@ paths: type: string tokenIndex: type: string + tx: + properties: + id: {} + type: + type: string + type: object type: enum: - mint @@ -7657,6 +7675,12 @@ paths: type: string tokenIndex: type: string + tx: + properties: + id: {} + type: + type: string + type: object type: enum: - mint @@ -7693,6 +7717,12 @@ paths: type: string tokenIndex: type: string + tx: + properties: + id: {} + type: + type: string + type: object type: enum: - mint @@ -7729,6 +7759,12 @@ paths: type: string tokenIndex: type: string + tx: + properties: + id: {} + type: + type: string + type: object type: enum: - mint @@ -7843,6 +7879,16 @@ paths: name: tokenindex schema: type: string + - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^' + in: query + name: tx.id + schema: + type: string + - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^' + in: query + name: tx.type + schema: + type: string - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^' in: query name: uri @@ -7909,6 +7955,12 @@ paths: type: string tokenIndex: type: string + tx: + properties: + id: {} + type: + type: string + type: object type: enum: - mint @@ -8054,6 +8106,12 @@ paths: type: string tokenIndex: type: string + tx: + properties: + id: {} + type: + type: string + type: object type: enum: - mint @@ -8090,6 +8148,12 @@ paths: type: string tokenIndex: type: string + tx: + properties: + id: {} + type: + type: string + type: object type: enum: - mint @@ -8126,6 +8190,12 @@ paths: type: string tokenIndex: type: string + tx: + properties: + id: {} + type: + type: string + type: object type: enum: - mint @@ -8540,6 +8610,12 @@ paths: type: string tokenIndex: type: string + tx: + properties: + id: {} + type: + type: string + type: object type: enum: - mint @@ -8576,6 +8652,12 @@ paths: type: string tokenIndex: type: string + tx: + properties: + id: {} + type: + type: string + type: object type: enum: - mint @@ -8612,6 +8694,12 @@ paths: type: string tokenIndex: type: string + tx: + properties: + id: {} + type: + type: string + type: object type: enum: - mint @@ -8776,6 +8864,12 @@ paths: type: string tokenIndex: type: string + tx: + properties: + id: {} + type: + type: string + type: object type: enum: - mint @@ -8812,6 +8906,12 @@ paths: type: string tokenIndex: type: string + tx: + properties: + id: {} + type: + type: string + type: object type: enum: - mint @@ -8848,6 +8948,12 @@ paths: type: string tokenIndex: type: string + tx: + properties: + id: {} + type: + type: string + type: object type: enum: - mint @@ -9322,6 +9428,16 @@ paths: name: tokenindex schema: type: string + - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^' + in: query + name: tx.id + schema: + type: string + - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^' + in: query + name: tx.type + schema: + type: string - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^' in: query name: uri @@ -9388,6 +9504,12 @@ paths: type: string tokenIndex: type: string + tx: + properties: + id: {} + type: + type: string + type: object type: enum: - mint @@ -9520,6 +9642,12 @@ paths: type: string tokenIndex: type: string + tx: + properties: + id: {} + type: + type: string + type: object type: enum: - mint @@ -9556,6 +9684,12 @@ paths: type: string tokenIndex: type: string + tx: + properties: + id: {} + type: + type: string + type: object type: enum: - mint @@ -9592,6 +9726,12 @@ paths: type: string tokenIndex: type: string + tx: + properties: + id: {} + type: + type: string + type: object type: enum: - mint @@ -9656,6 +9796,12 @@ paths: type: string tokenIndex: type: string + tx: + properties: + id: {} + type: + type: string + type: object type: enum: - mint diff --git a/internal/assets/token_transfer.go b/internal/assets/token_transfer.go index 6dc366d558..ca3fbebd20 100644 --- a/internal/assets/token_transfer.go +++ b/internal/assets/token_transfer.go @@ -253,6 +253,8 @@ func (s *transferSender) sendInternal(ctx context.Context, method sendMethod) er Created: fftypes.Now(), Status: fftypes.OpStatusPending, } + s.transfer.TX.ID = tx.ID + s.transfer.TX.Type = tx.Type op := fftypes.NewTXOperation( plugin, @@ -292,11 +294,11 @@ func (s *transferSender) sendInternal(ctx context.Context, method sendMethod) er switch s.transfer.Type { case fftypes.TokenTransferTypeMint: - err = plugin.MintTokens(ctx, op.ID, tx.ID, pool.ProtocolID, &s.transfer.TokenTransfer) + err = plugin.MintTokens(ctx, op.ID, pool.ProtocolID, &s.transfer.TokenTransfer) case fftypes.TokenTransferTypeTransfer: - err = plugin.TransferTokens(ctx, op.ID, tx.ID, pool.ProtocolID, &s.transfer.TokenTransfer) + err = plugin.TransferTokens(ctx, op.ID, pool.ProtocolID, &s.transfer.TokenTransfer) case fftypes.TokenTransferTypeBurn: - err = plugin.BurnTokens(ctx, op.ID, tx.ID, pool.ProtocolID, &s.transfer.TokenTransfer) + err = plugin.BurnTokens(ctx, op.ID, pool.ProtocolID, &s.transfer.TokenTransfer) default: panic(fmt.Sprintf("unknown transfer type: %v", s.transfer.Type)) } diff --git a/internal/assets/token_transfer_test.go b/internal/assets/token_transfer_test.go index 3c4026c88f..27ef4deaa9 100644 --- a/internal/assets/token_transfer_test.go +++ b/internal/assets/token_transfer_test.go @@ -126,7 +126,7 @@ func TestMintTokensSuccess(t *testing.T) { mim := am.identity.(*identitymanagermocks.Manager) mim.On("GetLocalOrganization", context.Background()).Return(&fftypes.Organization{Identity: "0x12345"}, nil) mdi.On("GetTokenPool", context.Background(), "ns1", "pool1").Return(pool, nil) - mti.On("MintTokens", context.Background(), mock.Anything, mock.Anything, "F1", &mint.TokenTransfer).Return(nil) + mti.On("MintTokens", context.Background(), mock.Anything, "F1", &mint.TokenTransfer).Return(nil) mdi.On("UpsertTransaction", context.Background(), mock.MatchedBy(func(tx *fftypes.Transaction) bool { return tx.Type == fftypes.TransactionTypeTokenTransfer })).Return(nil) @@ -156,7 +156,7 @@ func TestMintTokenUnknownConnectorSuccess(t *testing.T) { mim := am.identity.(*identitymanagermocks.Manager) mim.On("GetLocalOrganization", context.Background()).Return(&fftypes.Organization{Identity: "0x12345"}, nil) mdi.On("GetTokenPool", context.Background(), "ns1", "pool1").Return(pool, nil) - mti.On("MintTokens", context.Background(), mock.Anything, mock.Anything, "F1", &mint.TokenTransfer).Return(nil) + mti.On("MintTokens", context.Background(), mock.Anything, "F1", &mint.TokenTransfer).Return(nil) mdi.On("UpsertTransaction", context.Background(), mock.MatchedBy(func(tx *fftypes.Transaction) bool { return tx.Type == fftypes.TransactionTypeTokenTransfer })).Return(nil) @@ -277,7 +277,7 @@ func TestMintTokenUnknownPoolSuccess(t *testing.T) { return info.Count && info.Limit == 1 }))).Return(tokenPools, filterResult, nil) mdi.On("GetTokenPool", context.Background(), "ns1", "pool1").Return(tokenPools[0], nil) - mti.On("MintTokens", context.Background(), mock.Anything, mock.Anything, "F1", &mint.TokenTransfer).Return(nil) + mti.On("MintTokens", context.Background(), mock.Anything, "F1", &mint.TokenTransfer).Return(nil) mdi.On("UpsertTransaction", context.Background(), mock.MatchedBy(func(tx *fftypes.Transaction) bool { return tx.Type == fftypes.TransactionTypeTokenTransfer })).Return(nil) @@ -449,7 +449,7 @@ func TestMintTokensFail(t *testing.T) { mim := am.identity.(*identitymanagermocks.Manager) mim.On("GetLocalOrganization", context.Background()).Return(&fftypes.Organization{Identity: "0x12345"}, nil) mdi.On("GetTokenPool", context.Background(), "ns1", "pool1").Return(pool, nil) - mti.On("MintTokens", context.Background(), mock.Anything, mock.Anything, "F1", &mint.TokenTransfer).Return(fmt.Errorf("pop")) + mti.On("MintTokens", context.Background(), mock.Anything, "F1", &mint.TokenTransfer).Return(fmt.Errorf("pop")) mdi.On("UpsertTransaction", context.Background(), mock.MatchedBy(func(tx *fftypes.Transaction) bool { return tx.Type == fftypes.TransactionTypeTokenTransfer })).Return(nil) @@ -481,7 +481,7 @@ func TestMintTokensFailAndDbFail(t *testing.T) { mim := am.identity.(*identitymanagermocks.Manager) mim.On("GetLocalOrganization", context.Background()).Return(&fftypes.Organization{Identity: "0x12345"}, nil) mdi.On("GetTokenPool", context.Background(), "ns1", "pool1").Return(pool, nil) - mti.On("MintTokens", context.Background(), mock.Anything, mock.Anything, "F1", &mint.TokenTransfer).Return(fmt.Errorf("pop")) + mti.On("MintTokens", context.Background(), mock.Anything, "F1", &mint.TokenTransfer).Return(fmt.Errorf("pop")) mdi.On("InsertOperation", context.Background(), mock.Anything).Return(nil) mdi.On("UpsertTransaction", context.Background(), mock.MatchedBy(func(tx *fftypes.Transaction) bool { return tx.Type == fftypes.TransactionTypeTokenTransfer && tx.Status != fftypes.OpStatusFailed @@ -543,7 +543,7 @@ func TestMintTokensConfirm(t *testing.T) { mim := am.identity.(*identitymanagermocks.Manager) mim.On("GetLocalOrganization", context.Background()).Return(&fftypes.Organization{Identity: "0x12345"}, nil) mdi.On("GetTokenPool", context.Background(), "ns1", "pool1").Return(pool, nil) - mti.On("MintTokens", context.Background(), mock.Anything, mock.Anything, "F1", &mint.TokenTransfer).Return(nil) + mti.On("MintTokens", context.Background(), mock.Anything, "F1", &mint.TokenTransfer).Return(nil) mdi.On("UpsertTransaction", context.Background(), mock.MatchedBy(func(tx *fftypes.Transaction) bool { return tx.Type == fftypes.TransactionTypeTokenTransfer })).Return(nil) @@ -583,7 +583,7 @@ func TestMintTokensByTypeSuccess(t *testing.T) { mim := am.identity.(*identitymanagermocks.Manager) mim.On("GetLocalOrganization", context.Background()).Return(&fftypes.Organization{Identity: "0x12345"}, nil) mdi.On("GetTokenPool", context.Background(), "ns1", "pool1").Return(pool, nil) - mti.On("MintTokens", context.Background(), mock.Anything, mock.Anything, "F1", &mint.TokenTransfer).Return(nil) + mti.On("MintTokens", context.Background(), mock.Anything, "F1", &mint.TokenTransfer).Return(nil) mdi.On("UpsertTransaction", context.Background(), mock.MatchedBy(func(tx *fftypes.Transaction) bool { return tx.Type == fftypes.TransactionTypeTokenTransfer })).Return(nil) @@ -613,7 +613,7 @@ func TestBurnTokensSuccess(t *testing.T) { mim := am.identity.(*identitymanagermocks.Manager) mim.On("GetLocalOrganization", context.Background()).Return(&fftypes.Organization{Identity: "0x12345"}, nil) mdi.On("GetTokenPool", context.Background(), "ns1", "pool1").Return(pool, nil) - mti.On("BurnTokens", context.Background(), mock.Anything, mock.Anything, "F1", &burn.TokenTransfer).Return(nil) + mti.On("BurnTokens", context.Background(), mock.Anything, "F1", &burn.TokenTransfer).Return(nil) mdi.On("UpsertTransaction", context.Background(), mock.MatchedBy(func(tx *fftypes.Transaction) bool { return tx.Type == fftypes.TransactionTypeTokenTransfer })).Return(nil) @@ -667,7 +667,7 @@ func TestBurnTokensConfirm(t *testing.T) { mim := am.identity.(*identitymanagermocks.Manager) mim.On("GetLocalOrganization", context.Background()).Return(&fftypes.Organization{Identity: "0x12345"}, nil) mdi.On("GetTokenPool", context.Background(), "ns1", "pool1").Return(pool, nil) - mti.On("BurnTokens", context.Background(), mock.Anything, mock.Anything, "F1", &burn.TokenTransfer).Return(nil) + mti.On("BurnTokens", context.Background(), mock.Anything, "F1", &burn.TokenTransfer).Return(nil) mdi.On("UpsertTransaction", context.Background(), mock.MatchedBy(func(tx *fftypes.Transaction) bool { return tx.Type == fftypes.TransactionTypeTokenTransfer })).Return(nil) @@ -707,7 +707,7 @@ func TestBurnTokensByTypeSuccess(t *testing.T) { mim := am.identity.(*identitymanagermocks.Manager) mim.On("GetLocalOrganization", context.Background()).Return(&fftypes.Organization{Identity: "0x12345"}, nil) mdi.On("GetTokenPool", context.Background(), "ns1", "pool1").Return(pool, nil) - mti.On("BurnTokens", context.Background(), mock.Anything, mock.Anything, "F1", &burn.TokenTransfer).Return(nil) + mti.On("BurnTokens", context.Background(), mock.Anything, "F1", &burn.TokenTransfer).Return(nil) mdi.On("UpsertTransaction", context.Background(), mock.MatchedBy(func(tx *fftypes.Transaction) bool { return tx.Type == fftypes.TransactionTypeTokenTransfer })).Return(nil) @@ -743,7 +743,7 @@ func TestTransferTokensSuccess(t *testing.T) { mim := am.identity.(*identitymanagermocks.Manager) mim.On("GetLocalOrganization", context.Background()).Return(&fftypes.Organization{Identity: "0x12345"}, nil) mdi.On("GetTokenPool", context.Background(), "ns1", "pool1").Return(pool, nil) - mti.On("TransferTokens", context.Background(), mock.Anything, mock.Anything, "F1", &transfer.TokenTransfer).Return(nil) + mti.On("TransferTokens", context.Background(), mock.Anything, "F1", &transfer.TokenTransfer).Return(nil) mdi.On("UpsertTransaction", context.Background(), mock.MatchedBy(func(tx *fftypes.Transaction) bool { return tx.Type == fftypes.TransactionTypeTokenTransfer })).Return(nil) @@ -929,7 +929,7 @@ func TestTransferTokensWithBroadcastMessage(t *testing.T) { mms := &sysmessagingmocks.MessageSender{} mim.On("GetLocalOrganization", context.Background()).Return(&fftypes.Organization{Identity: "0x12345"}, nil) mdi.On("GetTokenPool", context.Background(), "ns1", "pool1").Return(pool, nil) - mti.On("TransferTokens", context.Background(), mock.Anything, mock.Anything, "F1", &transfer.TokenTransfer).Return(nil) + mti.On("TransferTokens", context.Background(), mock.Anything, "F1", &transfer.TokenTransfer).Return(nil) mdi.On("UpsertTransaction", context.Background(), mock.MatchedBy(func(tx *fftypes.Transaction) bool { return tx.Type == fftypes.TransactionTypeTokenTransfer })).Return(nil) @@ -1027,7 +1027,7 @@ func TestTransferTokensWithPrivateMessage(t *testing.T) { mms := &sysmessagingmocks.MessageSender{} mim.On("GetLocalOrganization", context.Background()).Return(&fftypes.Organization{Identity: "0x12345"}, nil) mdi.On("GetTokenPool", context.Background(), "ns1", "pool1").Return(pool, nil) - mti.On("TransferTokens", context.Background(), mock.Anything, mock.Anything, "F1", &transfer.TokenTransfer).Return(nil) + mti.On("TransferTokens", context.Background(), mock.Anything, "F1", &transfer.TokenTransfer).Return(nil) mdi.On("UpsertTransaction", context.Background(), mock.MatchedBy(func(tx *fftypes.Transaction) bool { return tx.Type == fftypes.TransactionTypeTokenTransfer })).Return(nil) @@ -1108,7 +1108,7 @@ func TestTransferTokensConfirm(t *testing.T) { mim := am.identity.(*identitymanagermocks.Manager) mim.On("GetLocalOrganization", context.Background()).Return(&fftypes.Organization{Identity: "0x12345"}, nil) mdi.On("GetTokenPool", context.Background(), "ns1", "pool1").Return(pool, nil) - mti.On("TransferTokens", context.Background(), mock.Anything, mock.Anything, "F1", &transfer.TokenTransfer).Return(nil) + mti.On("TransferTokens", context.Background(), mock.Anything, "F1", &transfer.TokenTransfer).Return(nil) mdi.On("UpsertTransaction", context.Background(), mock.MatchedBy(func(tx *fftypes.Transaction) bool { return tx.Type == fftypes.TransactionTypeTokenTransfer })).Return(nil) @@ -1169,7 +1169,7 @@ func TestTransferTokensWithBroadcastConfirm(t *testing.T) { msa := am.syncasync.(*syncasyncmocks.Bridge) mim.On("GetLocalOrganization", context.Background()).Return(&fftypes.Organization{Identity: "0x12345"}, nil) mdi.On("GetTokenPool", context.Background(), "ns1", "pool1").Return(pool, nil) - mti.On("TransferTokens", context.Background(), mock.Anything, mock.Anything, "F1", &transfer.TokenTransfer).Return(nil) + mti.On("TransferTokens", context.Background(), mock.Anything, "F1", &transfer.TokenTransfer).Return(nil) mdi.On("InsertOperation", context.Background(), mock.Anything).Return(nil) mdi.On("UpsertTransaction", context.Background(), mock.MatchedBy(func(tx *fftypes.Transaction) bool { return tx.Type == fftypes.TransactionTypeTokenTransfer @@ -1226,7 +1226,7 @@ func TestTransferTokensByTypeSuccess(t *testing.T) { mim := am.identity.(*identitymanagermocks.Manager) mim.On("GetLocalOrganization", context.Background()).Return(&fftypes.Organization{Identity: "0x12345"}, nil) mdi.On("GetTokenPool", context.Background(), "ns1", "pool1").Return(pool, nil) - mti.On("TransferTokens", context.Background(), mock.Anything, mock.Anything, "F1", &transfer.TokenTransfer).Return(nil) + mti.On("TransferTokens", context.Background(), mock.Anything, "F1", &transfer.TokenTransfer).Return(nil) mdi.On("UpsertTransaction", context.Background(), mock.MatchedBy(func(tx *fftypes.Transaction) bool { return tx.Type == fftypes.TransactionTypeTokenTransfer })).Return(nil) diff --git a/internal/database/sqlcommon/tokentransfer_sql.go b/internal/database/sqlcommon/tokentransfer_sql.go index 53e6b2d001..279b20b0b1 100644 --- a/internal/database/sqlcommon/tokentransfer_sql.go +++ b/internal/database/sqlcommon/tokentransfer_sql.go @@ -43,6 +43,8 @@ var ( "protocol_id", "message_id", "message_hash", + "tx_type", + "tx_id", "blockchain_event", "created", } @@ -55,6 +57,8 @@ var ( "protocolid": "protocol_id", "message": "message_id", "messagehash": "message_hash", + "tx.type": "tx_type", + "tx.id": "tx_id", "blockchainevent": "blockchain_event", } ) @@ -93,6 +97,8 @@ func (s *SQLCommon) UpsertTokenTransfer(ctx context.Context, transfer *fftypes.T Set("amount", transfer.Amount). Set("message_id", transfer.Message). Set("message_hash", transfer.MessageHash). + Set("tx_type", transfer.TX.Type). + Set("tx_id", transfer.TX.ID). Set("blockchain_event", transfer.BlockchainEvent). Where(sq.Eq{"protocol_id": transfer.ProtocolID}), func() { @@ -121,6 +127,8 @@ func (s *SQLCommon) UpsertTokenTransfer(ctx context.Context, transfer *fftypes.T transfer.ProtocolID, transfer.Message, transfer.MessageHash, + transfer.TX.Type, + transfer.TX.ID, transfer.BlockchainEvent, transfer.Created, ), @@ -152,6 +160,8 @@ func (s *SQLCommon) tokenTransferResult(ctx context.Context, row *sql.Rows) (*ff &transfer.ProtocolID, &transfer.Message, &transfer.MessageHash, + &transfer.TX.Type, + &transfer.TX.ID, &transfer.BlockchainEvent, &transfer.Created, ) diff --git a/internal/database/sqlcommon/tokentransfer_sql_test.go b/internal/database/sqlcommon/tokentransfer_sql_test.go index 211b221cde..9ef8934aa7 100644 --- a/internal/database/sqlcommon/tokentransfer_sql_test.go +++ b/internal/database/sqlcommon/tokentransfer_sql_test.go @@ -36,18 +36,22 @@ func TestTokenTransferE2EWithDB(t *testing.T) { // Create a new token transfer entry transfer := &fftypes.TokenTransfer{ - LocalID: fftypes.NewUUID(), - Type: fftypes.TokenTransferTypeTransfer, - Pool: fftypes.NewUUID(), - TokenIndex: "1", - URI: "firefly://token/1", - Connector: "erc1155", - Namespace: "ns1", - From: "0x01", - To: "0x02", - ProtocolID: "12345", - Message: fftypes.NewUUID(), - MessageHash: fftypes.NewRandB32(), + LocalID: fftypes.NewUUID(), + Type: fftypes.TokenTransferTypeTransfer, + Pool: fftypes.NewUUID(), + TokenIndex: "1", + URI: "firefly://token/1", + Connector: "erc1155", + Namespace: "ns1", + From: "0x01", + To: "0x02", + ProtocolID: "12345", + Message: fftypes.NewUUID(), + MessageHash: fftypes.NewRandB32(), + TX: fftypes.TransactionRef{ + Type: fftypes.TransactionTypeTokenTransfer, + ID: fftypes.NewUUID(), + }, BlockchainEvent: fftypes.NewUUID(), } transfer.Amount.Int().SetInt64(10) diff --git a/internal/events/tokens_transferred_test.go b/internal/events/tokens_transferred_test.go index 4ae5aaafbb..9e27f87a2e 100644 --- a/internal/events/tokens_transferred_test.go +++ b/internal/events/tokens_transferred_test.go @@ -42,10 +42,10 @@ func newTransfer() *tokens.TokenTransfer { ProtocolID: "123", URI: "firefly://token/1", Amount: *fftypes.NewFFBigInt(1), - }, - TX: fftypes.TransactionRef{ - ID: fftypes.NewUUID(), - Type: fftypes.TransactionTypeTokenTransfer, + TX: fftypes.TransactionRef{ + ID: fftypes.NewUUID(), + Type: fftypes.TransactionTypeTokenTransfer, + }, }, Event: blockchain.Event{ Name: "Transfer", diff --git a/internal/tokens/fftokens/fftokens.go b/internal/tokens/fftokens/fftokens.go index e79a4b5431..222bfffec0 100644 --- a/internal/tokens/fftokens/fftokens.go +++ b/internal/tokens/fftokens/fftokens.go @@ -295,10 +295,10 @@ func (ft *FFTokens) handleTokenTransfer(ctx context.Context, t fftypes.TokenTran Key: operatorAddress, Message: transferData.Message, MessageHash: transferData.MessageHash, - }, - TX: fftypes.TransactionRef{ - ID: transferData.TX, - Type: fftypes.TransactionTypeTokenTransfer, + TX: fftypes.TransactionRef{ + ID: transferData.TX, + Type: fftypes.TransactionTypeTokenTransfer, + }, }, Event: blockchain.Event{ Source: ft.Name() + ":" + ft.configuredName, @@ -405,9 +405,9 @@ func (ft *FFTokens) ActivateTokenPool(ctx context.Context, opID *fftypes.UUID, p return nil } -func (ft *FFTokens) MintTokens(ctx context.Context, opID, txID *fftypes.UUID, poolProtocolID string, mint *fftypes.TokenTransfer) error { +func (ft *FFTokens) MintTokens(ctx context.Context, opID *fftypes.UUID, poolProtocolID string, mint *fftypes.TokenTransfer) error { data, _ := json.Marshal(tokenData{ - TX: txID, + TX: mint.TX.ID, Message: mint.Message, MessageHash: mint.MessageHash, }) @@ -427,9 +427,9 @@ func (ft *FFTokens) MintTokens(ctx context.Context, opID, txID *fftypes.UUID, po return nil } -func (ft *FFTokens) BurnTokens(ctx context.Context, opID, txID *fftypes.UUID, poolProtocolID string, burn *fftypes.TokenTransfer) error { +func (ft *FFTokens) BurnTokens(ctx context.Context, opID *fftypes.UUID, poolProtocolID string, burn *fftypes.TokenTransfer) error { data, _ := json.Marshal(tokenData{ - TX: txID, + TX: burn.TX.ID, Message: burn.Message, MessageHash: burn.MessageHash, }) @@ -450,9 +450,9 @@ func (ft *FFTokens) BurnTokens(ctx context.Context, opID, txID *fftypes.UUID, po return nil } -func (ft *FFTokens) TransferTokens(ctx context.Context, opID, txID *fftypes.UUID, poolProtocolID string, transfer *fftypes.TokenTransfer) error { +func (ft *FFTokens) TransferTokens(ctx context.Context, opID *fftypes.UUID, poolProtocolID string, transfer *fftypes.TokenTransfer) error { data, _ := json.Marshal(tokenData{ - TX: txID, + TX: transfer.TX.ID, Message: transfer.Message, MessageHash: transfer.MessageHash, }) diff --git a/internal/tokens/fftokens/fftokens_test.go b/internal/tokens/fftokens/fftokens_test.go index e3e30cc7f8..82a5e858a2 100644 --- a/internal/tokens/fftokens/fftokens_test.go +++ b/internal/tokens/fftokens/fftokens_test.go @@ -235,9 +235,12 @@ func TestMintTokens(t *testing.T) { To: "user1", Key: "0x123", Amount: *fftypes.NewFFBigInt(10), + TX: fftypes.TransactionRef{ + ID: fftypes.NewUUID(), + Type: fftypes.TransactionTypeTokenTransfer, + }, } opID := fftypes.NewUUID() - txID := fftypes.NewUUID() httpmock.RegisterResponder("POST", fmt.Sprintf("%s/api/v1/mint", httpURL), func(req *http.Request) (*http.Response, error) { @@ -250,7 +253,7 @@ func TestMintTokens(t *testing.T) { "amount": "10", "operator": "0x123", "requestId": opID.String(), - "data": `{"tx":"` + txID.String() + `"}`, + "data": `{"tx":"` + mint.TX.ID.String() + `"}`, }, body) res := &http.Response{ @@ -263,7 +266,7 @@ func TestMintTokens(t *testing.T) { return res, nil }) - err := h.MintTokens(context.Background(), opID, txID, "123", mint) + err := h.MintTokens(context.Background(), opID, "123", mint) assert.NoError(t, err) } @@ -276,7 +279,7 @@ func TestMintTokensError(t *testing.T) { httpmock.RegisterResponder("POST", fmt.Sprintf("%s/api/v1/mint", httpURL), httpmock.NewJsonResponderOrPanic(500, fftypes.JSONObject{})) - err := h.MintTokens(context.Background(), fftypes.NewUUID(), fftypes.NewUUID(), "F1", mint) + err := h.MintTokens(context.Background(), fftypes.NewUUID(), "F1", mint) assert.Regexp(t, "FF10274", err) } @@ -290,9 +293,12 @@ func TestBurnTokens(t *testing.T) { From: "user1", Key: "0x123", Amount: *fftypes.NewFFBigInt(10), + TX: fftypes.TransactionRef{ + ID: fftypes.NewUUID(), + Type: fftypes.TransactionTypeTokenTransfer, + }, } opID := fftypes.NewUUID() - txID := fftypes.NewUUID() httpmock.RegisterResponder("POST", fmt.Sprintf("%s/api/v1/burn", httpURL), func(req *http.Request) (*http.Response, error) { @@ -306,7 +312,7 @@ func TestBurnTokens(t *testing.T) { "amount": "10", "operator": "0x123", "requestId": opID.String(), - "data": `{"tx":"` + txID.String() + `"}`, + "data": `{"tx":"` + burn.TX.ID.String() + `"}`, }, body) res := &http.Response{ @@ -319,7 +325,7 @@ func TestBurnTokens(t *testing.T) { return res, nil }) - err := h.BurnTokens(context.Background(), opID, txID, "123", burn) + err := h.BurnTokens(context.Background(), opID, "123", burn) assert.NoError(t, err) } @@ -332,7 +338,7 @@ func TestBurnTokensError(t *testing.T) { httpmock.RegisterResponder("POST", fmt.Sprintf("%s/api/v1/burn", httpURL), httpmock.NewJsonResponderOrPanic(500, fftypes.JSONObject{})) - err := h.BurnTokens(context.Background(), fftypes.NewUUID(), fftypes.NewUUID(), "F1", burn) + err := h.BurnTokens(context.Background(), fftypes.NewUUID(), "F1", burn) assert.Regexp(t, "FF10274", err) } @@ -347,9 +353,12 @@ func TestTransferTokens(t *testing.T) { To: "user2", Key: "0x123", Amount: *fftypes.NewFFBigInt(10), + TX: fftypes.TransactionRef{ + ID: fftypes.NewUUID(), + Type: fftypes.TransactionTypeTokenTransfer, + }, } opID := fftypes.NewUUID() - txID := fftypes.NewUUID() httpmock.RegisterResponder("POST", fmt.Sprintf("%s/api/v1/transfer", httpURL), func(req *http.Request) (*http.Response, error) { @@ -364,7 +373,7 @@ func TestTransferTokens(t *testing.T) { "amount": "10", "operator": "0x123", "requestId": opID.String(), - "data": `{"tx":"` + txID.String() + `"}`, + "data": `{"tx":"` + transfer.TX.ID.String() + `"}`, }, body) res := &http.Response{ @@ -377,7 +386,7 @@ func TestTransferTokens(t *testing.T) { return res, nil }) - err := h.TransferTokens(context.Background(), opID, txID, "123", transfer) + err := h.TransferTokens(context.Background(), opID, "123", transfer) assert.NoError(t, err) } @@ -390,7 +399,7 @@ func TestTransferTokensError(t *testing.T) { httpmock.RegisterResponder("POST", fmt.Sprintf("%s/api/v1/transfer", httpURL), httpmock.NewJsonResponderOrPanic(500, fftypes.JSONObject{})) - err := h.TransferTokens(context.Background(), fftypes.NewUUID(), fftypes.NewUUID(), "F1", transfer) + err := h.TransferTokens(context.Background(), fftypes.NewUUID(), "F1", transfer) assert.Regexp(t, "FF10274", err) } diff --git a/mocks/tokenmocks/plugin.go b/mocks/tokenmocks/plugin.go index 34b9c8d3a2..f8b7475761 100644 --- a/mocks/tokenmocks/plugin.go +++ b/mocks/tokenmocks/plugin.go @@ -33,13 +33,13 @@ func (_m *Plugin) ActivateTokenPool(ctx context.Context, opID *fftypes.UUID, poo return r0 } -// BurnTokens provides a mock function with given fields: ctx, opID, txID, poolProtocolID, burn -func (_m *Plugin) BurnTokens(ctx context.Context, opID *fftypes.UUID, txID *fftypes.UUID, poolProtocolID string, burn *fftypes.TokenTransfer) error { - ret := _m.Called(ctx, opID, txID, poolProtocolID, burn) +// BurnTokens provides a mock function with given fields: ctx, opID, poolProtocolID, burn +func (_m *Plugin) BurnTokens(ctx context.Context, opID *fftypes.UUID, poolProtocolID string, burn *fftypes.TokenTransfer) error { + ret := _m.Called(ctx, opID, poolProtocolID, burn) var r0 error - if rf, ok := ret.Get(0).(func(context.Context, *fftypes.UUID, *fftypes.UUID, string, *fftypes.TokenTransfer) error); ok { - r0 = rf(ctx, opID, txID, poolProtocolID, burn) + if rf, ok := ret.Get(0).(func(context.Context, *fftypes.UUID, string, *fftypes.TokenTransfer) error); ok { + r0 = rf(ctx, opID, poolProtocolID, burn) } else { r0 = ret.Error(0) } @@ -96,13 +96,13 @@ func (_m *Plugin) InitPrefix(prefix config.PrefixArray) { _m.Called(prefix) } -// MintTokens provides a mock function with given fields: ctx, opID, txID, poolProtocolID, mint -func (_m *Plugin) MintTokens(ctx context.Context, opID *fftypes.UUID, txID *fftypes.UUID, poolProtocolID string, mint *fftypes.TokenTransfer) error { - ret := _m.Called(ctx, opID, txID, poolProtocolID, mint) +// MintTokens provides a mock function with given fields: ctx, opID, poolProtocolID, mint +func (_m *Plugin) MintTokens(ctx context.Context, opID *fftypes.UUID, poolProtocolID string, mint *fftypes.TokenTransfer) error { + ret := _m.Called(ctx, opID, poolProtocolID, mint) var r0 error - if rf, ok := ret.Get(0).(func(context.Context, *fftypes.UUID, *fftypes.UUID, string, *fftypes.TokenTransfer) error); ok { - r0 = rf(ctx, opID, txID, poolProtocolID, mint) + if rf, ok := ret.Get(0).(func(context.Context, *fftypes.UUID, string, *fftypes.TokenTransfer) error); ok { + r0 = rf(ctx, opID, poolProtocolID, mint) } else { r0 = ret.Error(0) } @@ -138,13 +138,13 @@ func (_m *Plugin) Start() error { return r0 } -// TransferTokens provides a mock function with given fields: ctx, opID, txID, poolProtocolID, transfer -func (_m *Plugin) TransferTokens(ctx context.Context, opID *fftypes.UUID, txID *fftypes.UUID, poolProtocolID string, transfer *fftypes.TokenTransfer) error { - ret := _m.Called(ctx, opID, txID, poolProtocolID, transfer) +// TransferTokens provides a mock function with given fields: ctx, opID, poolProtocolID, transfer +func (_m *Plugin) TransferTokens(ctx context.Context, opID *fftypes.UUID, poolProtocolID string, transfer *fftypes.TokenTransfer) error { + ret := _m.Called(ctx, opID, poolProtocolID, transfer) var r0 error - if rf, ok := ret.Get(0).(func(context.Context, *fftypes.UUID, *fftypes.UUID, string, *fftypes.TokenTransfer) error); ok { - r0 = rf(ctx, opID, txID, poolProtocolID, transfer) + if rf, ok := ret.Get(0).(func(context.Context, *fftypes.UUID, string, *fftypes.TokenTransfer) error); ok { + r0 = rf(ctx, opID, poolProtocolID, transfer) } else { r0 = ret.Error(0) } diff --git a/pkg/database/plugin.go b/pkg/database/plugin.go index 33698aeb1f..51162e0bfa 100644 --- a/pkg/database/plugin.go +++ b/pkg/database/plugin.go @@ -906,6 +906,8 @@ var TokenTransferQueryFactory = &queryFields{ "message": &UUIDField{}, "messagehash": &Bytes32Field{}, "created": &TimeField{}, + "tx.type": &StringField{}, + "tx.id": &UUIDField{}, "blockchainevent": &UUIDField{}, } diff --git a/pkg/fftypes/tokentransfer.go b/pkg/fftypes/tokentransfer.go index 493225fa18..5e3bd75bc9 100644 --- a/pkg/fftypes/tokentransfer.go +++ b/pkg/fftypes/tokentransfer.go @@ -40,6 +40,7 @@ type TokenTransfer struct { Message *UUID `json:"message,omitempty"` MessageHash *Bytes32 `json:"messageHash,omitempty"` Created *FFTime `json:"created,omitempty"` + TX TransactionRef `json:"tx"` BlockchainEvent *UUID `json:"blockchainEvent,omitempty"` } diff --git a/pkg/tokens/plugin.go b/pkg/tokens/plugin.go index c859ee3273..62434ea39c 100644 --- a/pkg/tokens/plugin.go +++ b/pkg/tokens/plugin.go @@ -48,13 +48,13 @@ type Plugin interface { ActivateTokenPool(ctx context.Context, opID *fftypes.UUID, pool *fftypes.TokenPool, event *fftypes.BlockchainEvent) error // MintTokens mints new tokens in a pool and adds them to the recipient's account - MintTokens(ctx context.Context, opID, txID *fftypes.UUID, poolProtocolID string, mint *fftypes.TokenTransfer) error + MintTokens(ctx context.Context, opID *fftypes.UUID, poolProtocolID string, mint *fftypes.TokenTransfer) error // BurnTokens burns tokens from an account - BurnTokens(ctx context.Context, opID, txID *fftypes.UUID, poolProtocolID string, burn *fftypes.TokenTransfer) error + BurnTokens(ctx context.Context, opID *fftypes.UUID, poolProtocolID string, burn *fftypes.TokenTransfer) error // TransferTokens transfers tokens within a pool from one account to another - TransferTokens(ctx context.Context, opID, txID *fftypes.UUID, poolProtocolID string, transfer *fftypes.TokenTransfer) error + TransferTokens(ctx context.Context, opID *fftypes.UUID, poolProtocolID string, transfer *fftypes.TokenTransfer) error } // Callbacks is the interface provided to the tokens plugin, to allow it to pass events back to firefly. @@ -122,7 +122,4 @@ type TokenTransfer struct { // Event contains info on the underlying blockchain event for this transfer Event blockchain.Event - - // TX contains info on the containing Transaction, if this transfer came from FireFly - TX fftypes.TransactionRef }