diff --git a/x/ccv/provider/keeper/consumer_lifecycle.go b/x/ccv/provider/keeper/consumer_lifecycle.go index 5f806b0e6d..08b55b3ced 100644 --- a/x/ccv/provider/keeper/consumer_lifecycle.go +++ b/x/ccv/provider/keeper/consumer_lifecycle.go @@ -97,6 +97,21 @@ func (k Keeper) BeginBlockLaunchConsumers(ctx sdk.Context) error { ctx.Logger().Error("could not launch chain", "consumerId", consumerId, "error", err) + + // reset spawn time to zero so that owner can try again later + initializationRecord, err := k.GetConsumerInitializationParameters(ctx, consumerId) + if err != nil { + return errorsmod.Wrapf(ccv.ErrInvalidConsumerState, + "getting initialization parameters, consumerId(%s): %s", consumerId, err.Error()) + } + initializationRecord.SpawnTime = time.Time{} + err = k.SetConsumerInitializationParameters(ctx, consumerId, initializationRecord) + if err != nil { + return fmt.Errorf("setting consumer initialization parameters, consumerId(%s): %w", consumerId, err) + } + // also set the phase to registered + k.SetConsumerPhase(ctx, consumerId, types.CONSUMER_PHASE_REGISTERED) + continue } diff --git a/x/ccv/provider/keeper/consumer_lifecycle_test.go b/x/ccv/provider/keeper/consumer_lifecycle_test.go index 9f7eec3d69..3561cb8c46 100644 --- a/x/ccv/provider/keeper/consumer_lifecycle_test.go +++ b/x/ccv/provider/keeper/consumer_lifecycle_test.go @@ -322,7 +322,7 @@ func TestBeginBlockLaunchConsumers(t *testing.T) { // fifth chain corresponds to an Opt-In chain with no opted-in validators and hence the // chain launch is NOT successful phase = providerKeeper.GetConsumerPhase(ctx, "4") - require.Equal(t, providertypes.CONSUMER_PHASE_INITIALIZED, phase) + require.Equal(t, providertypes.CONSUMER_PHASE_REGISTERED, phase) _, found = providerKeeper.GetConsumerGenesis(ctx, "4") require.False(t, found) } diff --git a/x/ccv/provider/keeper/msg_server.go b/x/ccv/provider/keeper/msg_server.go index a1f057b3ee..ff1c082183 100644 --- a/x/ccv/provider/keeper/msg_server.go +++ b/x/ccv/provider/keeper/msg_server.go @@ -406,7 +406,7 @@ func (k msgServer) CreateConsumer(goCtx context.Context, msg *types.MsgCreateCon if spawnTime, initialized := k.Keeper.InitializeConsumer(ctx, consumerId); initialized { if err := k.Keeper.PrepareConsumerForLaunch(ctx, consumerId, time.Time{}, spawnTime); err != nil { return &resp, errorsmod.Wrapf(ccvtypes.ErrInvalidConsumerState, - "cannot prepare chain with consumer id (%s) for launch", consumerId) + "prepare consumer for launch, consumerId(%s), spawnTime(%s): %s", consumerId, spawnTime, err.Error()) } // add SpawnTime event attribute @@ -584,7 +584,8 @@ func (k msgServer) UpdateConsumer(goCtx context.Context, msg *types.MsgUpdateCon if spawnTime, initialized := k.Keeper.InitializeConsumer(ctx, consumerId); initialized { if err := k.Keeper.PrepareConsumerForLaunch(ctx, consumerId, previousSpawnTime, spawnTime); err != nil { return &resp, errorsmod.Wrapf(ccvtypes.ErrInvalidConsumerState, - "cannot prepare chain with consumer id (%s) for launch", consumerId) + "prepare consumer for launch, consumerId(%s), previousSpawnTime(%s), spawnTime(%s): %s", + consumerId, previousSpawnTime, spawnTime, err.Error()) } }