Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion db/migrations/postgres/000044_add_tokenpool_state.up.sql
Original file line number Diff line number Diff line change
@@ -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;
2 changes: 1 addition & 1 deletion db/migrations/sqlite/000044_add_tokenpool_state.up.sql
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
ALTER TABLE tokenpool ADD COLUMN state VARCHAR(64);
UPDATE tokenpool SET state="unknown";
UPDATE tokenpool SET state="confirmed";
2 changes: 1 addition & 1 deletion docs/reference/types/tokenpool.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`:<br/>`"unknown"`<br/>`"pending"`<br/>`"confirmed"` |
| `state` | The current state of the token pool | `FFEnum`:<br/>`"pending"`<br/>`"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) |
Expand Down
8 changes: 0 additions & 8 deletions docs/swagger/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25495,7 +25495,6 @@ paths:
state:
description: The current state of the token pool
enum:
- unknown
- pending
- confirmed
type: string
Expand Down Expand Up @@ -25656,7 +25655,6 @@ paths:
state:
description: The current state of the token pool
enum:
- unknown
- pending
- confirmed
type: string
Expand Down Expand Up @@ -25742,7 +25740,6 @@ paths:
state:
description: The current state of the token pool
enum:
- unknown
- pending
- confirmed
type: string
Expand Down Expand Up @@ -25858,7 +25855,6 @@ paths:
state:
description: The current state of the token pool
enum:
- unknown
- pending
- confirmed
type: string
Expand Down Expand Up @@ -32786,7 +32782,6 @@ paths:
state:
description: The current state of the token pool
enum:
- unknown
- pending
- confirmed
type: string
Expand Down Expand Up @@ -32940,7 +32935,6 @@ paths:
state:
description: The current state of the token pool
enum:
- unknown
- pending
- confirmed
type: string
Expand Down Expand Up @@ -33026,7 +33020,6 @@ paths:
state:
description: The current state of the token pool
enum:
- unknown
- pending
- confirmed
type: string
Expand Down Expand Up @@ -33135,7 +33128,6 @@ paths:
state:
description: The current state of the token pool
enum:
- unknown
- pending
- confirmed
type: string
Expand Down
20 changes: 5 additions & 15 deletions internal/events/token_pool_created.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
}
Expand All @@ -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
Expand Down
50 changes: 0 additions & 50 deletions internal/events/token_pool_created_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
3 changes: 0 additions & 3 deletions pkg/core/tokenpool.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down