diff --git a/db/migrations/postgres/000044_add_tokenpool_state.up.sql b/db/migrations/postgres/000044_add_tokenpool_state.up.sql index 0fde5e8514..85c8a3ed6f 100644 --- a/db/migrations/postgres/000044_add_tokenpool_state.up.sql +++ b/db/migrations/postgres/000044_add_tokenpool_state.up.sql @@ -1,5 +1,5 @@ BEGIN; ALTER TABLE tokenpool ADD COLUMN state VARCHAR(64); -UPDATE tokenpool SET state='unknown'; +UPDATE tokenpool SET state='confirmed'; ALTER TABLE tokenpool ALTER COLUMN state SET NOT NULL; COMMIT; diff --git a/db/migrations/sqlite/000044_add_tokenpool_state.up.sql b/db/migrations/sqlite/000044_add_tokenpool_state.up.sql index 6aeb17a2f1..a1f4542eee 100644 --- a/db/migrations/sqlite/000044_add_tokenpool_state.up.sql +++ b/db/migrations/sqlite/000044_add_tokenpool_state.up.sql @@ -1,2 +1,2 @@ ALTER TABLE tokenpool ADD COLUMN state VARCHAR(64); -UPDATE tokenpool SET state="unknown"; +UPDATE tokenpool SET state="confirmed"; diff --git a/docs/reference/types/tokenpool.md b/docs/reference/types/tokenpool.md index d61c8e5aae..8dfd14c526 100644 --- a/docs/reference/types/tokenpool.md +++ b/docs/reference/types/tokenpool.md @@ -62,7 +62,7 @@ nav_order: 10 | `decimals` | Number of decimal places that this token has | `int` | | `connector` | The name of the token connector, as specified in the FireFly core configuration file that is responsible for the token pool. Required on input when multiple token connectors are configured | `string` | | `message` | The UUID of the broadcast message used to inform the network to index this pool | [`UUID`](simpletypes#uuid) | -| `state` | The current state of the token pool | `FFEnum`:
`"unknown"`
`"pending"`
`"confirmed"` | +| `state` | The current state of the token pool | `FFEnum`:
`"pending"`
`"confirmed"` | | `created` | The creation time of the pool | [`FFTime`](simpletypes#fftime) | | `config` | Input only field, with token connector specific configuration of the pool, such as an existing Ethereum address and block number to used to index the pool. See your chosen token connector documentation for details | [`JSONObject`](simpletypes#jsonobject) | | `info` | Token connector specific information about the pool. See your chosen token connector documentation for details | [`JSONObject`](simpletypes#jsonobject) | diff --git a/docs/swagger/swagger.yaml b/docs/swagger/swagger.yaml index bcf5d5d5d3..3b0e0a5228 100644 --- a/docs/swagger/swagger.yaml +++ b/docs/swagger/swagger.yaml @@ -25495,7 +25495,6 @@ paths: state: description: The current state of the token pool enum: - - unknown - pending - confirmed type: string @@ -25656,7 +25655,6 @@ paths: state: description: The current state of the token pool enum: - - unknown - pending - confirmed type: string @@ -25742,7 +25740,6 @@ paths: state: description: The current state of the token pool enum: - - unknown - pending - confirmed type: string @@ -25858,7 +25855,6 @@ paths: state: description: The current state of the token pool enum: - - unknown - pending - confirmed type: string @@ -32786,7 +32782,6 @@ paths: state: description: The current state of the token pool enum: - - unknown - pending - confirmed type: string @@ -32940,7 +32935,6 @@ paths: state: description: The current state of the token pool enum: - - unknown - pending - confirmed type: string @@ -33026,7 +33020,6 @@ paths: state: description: The current state of the token pool enum: - - unknown - pending - confirmed type: string @@ -33135,7 +33128,6 @@ paths: state: description: The current state of the token pool enum: - - unknown - pending - confirmed type: string diff --git a/internal/events/token_pool_created.go b/internal/events/token_pool_created.go index 917c89ed96..627f4491f8 100644 --- a/internal/events/token_pool_created.go +++ b/internal/events/token_pool_created.go @@ -93,30 +93,20 @@ func (em *eventManager) findTXOperation(ctx context.Context, tx *fftypes.UUID, o return nil, nil } -func (em *eventManager) shouldConfirm(ctx context.Context, pool *tokens.TokenPool) (existingPool *core.TokenPool, err error) { +func (em *eventManager) loadExisting(ctx context.Context, pool *tokens.TokenPool) (existingPool *core.TokenPool, err error) { if existingPool, err = em.database.GetTokenPoolByLocator(ctx, em.namespace.Name, pool.Connector, pool.PoolLocator); err != nil || existingPool == nil { log.L(ctx).Debugf("Pool not found with ns=%s connector=%s locator=%s (err=%v)", em.namespace.Name, pool.Connector, pool.PoolLocator, err) return existingPool, err } + if err = addPoolDetailsFromPlugin(existingPool, pool); err != nil { log.L(ctx).Errorf("Error processing pool for transaction '%s' (%s) - ignoring", pool.TX.ID, err) return nil, nil } - - log.L(ctx).Debugf("shouldConfirm checking pool: state=%s name=%s connector=%s locator=%s", existingPool.State, em.namespace.Name, pool.Connector, pool.PoolLocator) - if existingPool.State == core.TokenPoolStateUnknown { - // Unknown pool state - should only happen on first run after database migration - // Activate the pool, then immediately confirm - // TODO: can this state eventually be removed? - if err = em.assets.ActivateTokenPool(ctx, existingPool); err != nil { - log.L(ctx).Errorf("Failed to activate token pool '%s': %s", existingPool.ID, err) - return nil, err - } - } return existingPool, nil } -func (em *eventManager) shouldAnnounce(ctx context.Context, pool *tokens.TokenPool) (announcePool *core.TokenPool, err error) { +func (em *eventManager) loadFromOperation(ctx context.Context, pool *tokens.TokenPool) (announcePool *core.TokenPool, err error) { op, err := em.findTXOperation(ctx, pool.TX.ID, core.OpTypeTokenCreatePool) if err != nil { return nil, err @@ -148,7 +138,7 @@ func (em *eventManager) TokenPoolCreated(ti tokens.Plugin, pool *tokens.TokenPoo err = em.retry.Do(em.ctx, "persist token pool transaction", func(attempt int) (bool, error) { err := em.database.RunAsGroup(em.ctx, func(ctx context.Context) error { // See if this is a confirmation of an unconfirmed pool - existingPool, err := em.shouldConfirm(ctx, pool) + existingPool, err := em.loadExisting(ctx, pool) if err != nil { return err } @@ -167,7 +157,7 @@ func (em *eventManager) TokenPoolCreated(ti tokens.Plugin, pool *tokens.TokenPoo } // See if this pool was submitted locally and needs to be announced - if announcePool, err = em.shouldAnnounce(ctx, pool); err != nil { + if announcePool, err = em.loadFromOperation(ctx, pool); err != nil { return err } else if announcePool != nil { return nil // trigger announce after completion of database transaction diff --git a/internal/events/token_pool_created_test.go b/internal/events/token_pool_created_test.go index 8eb6125056..45e3d74a03 100644 --- a/internal/events/token_pool_created_test.go +++ b/internal/events/token_pool_created_test.go @@ -225,56 +225,6 @@ func TestTokenPoolCreatedConfirmFailBadSymbol(t *testing.T) { } -func TestTokenPoolCreatedMigrate(t *testing.T) { - em := newTestEventManager(t) - defer em.cleanup(t) - mti := &tokenmocks.Plugin{} - - txID := fftypes.NewUUID() - chainPool := &tokens.TokenPool{ - Type: core.TokenTypeFungible, - PoolLocator: "123", - Connector: "magic-tokens", - TX: core.TransactionRef{ - ID: txID, - Type: core.TransactionTypeTokenPool, - }, - Event: &blockchain.Event{ - BlockchainTXID: "0xffffeeee", - ProtocolID: "tx1", - Info: fftypes.JSONObject{"some": "info"}, - }, - } - storedPool := &core.TokenPool{ - Namespace: "ns1", - ID: fftypes.NewUUID(), - State: core.TokenPoolStateUnknown, - TX: core.TransactionRef{ - Type: core.TransactionTypeTokenPool, - ID: txID, - }, - } - - em.mdi.On("GetTokenPoolByLocator", em.ctx, "ns1", "magic-tokens", "123").Return(storedPool, nil).Times(2) - em.mth.On("InsertOrGetBlockchainEvent", em.ctx, mock.MatchedBy(func(e *core.BlockchainEvent) bool { - return e.Name == chainPool.Event.Name - })).Return(nil, nil).Once() - em.mdi.On("InsertEvent", em.ctx, mock.MatchedBy(func(e *core.Event) bool { - return e.Type == core.EventTypeBlockchainEventReceived - })).Return(nil).Once() - em.mth.On("PersistTransaction", mock.Anything, txID, core.TransactionTypeTokenPool, "0xffffeeee").Return(true, nil).Once() - em.mdi.On("UpsertTokenPool", em.ctx, storedPool).Return(nil).Once() - em.mdi.On("InsertEvent", em.ctx, mock.MatchedBy(func(e *core.Event) bool { - return e.Type == core.EventTypePoolConfirmed && *e.Reference == *storedPool.ID - })).Return(nil).Once() - em.mam.On("ActivateTokenPool", em.ctx, storedPool).Return(fmt.Errorf("pop")).Once() - em.mam.On("ActivateTokenPool", em.ctx, storedPool).Return(nil).Once() - - err := em.TokenPoolCreated(mti, chainPool) - assert.NoError(t, err) - -} - func TestConfirmPoolBlockchainEventFail(t *testing.T) { em := newTestEventManager(t) defer em.cleanup(t) diff --git a/pkg/core/tokenpool.go b/pkg/core/tokenpool.go index 6886105c06..69d31d6819 100644 --- a/pkg/core/tokenpool.go +++ b/pkg/core/tokenpool.go @@ -33,9 +33,6 @@ var ( type TokenPoolState = fftypes.FFEnum var ( - // TokenPoolStateUnknown is a token pool that may not yet be activated - // (should not be used in the code - only set via database migration for previously-created pools) - TokenPoolStateUnknown = fftypes.FFEnumValue("tokenpoolstate", "unknown") // TokenPoolStatePending is a token pool that has been announced but not yet confirmed TokenPoolStatePending = fftypes.FFEnumValue("tokenpoolstate", "pending") // TokenPoolStateConfirmed is a token pool that has been confirmed on chain