func ValidRelationshipsInvariant(k Keeper) sdk.Invariant {
	return func(ctx sdk.Context) (string, bool) {
		var invalidRelationships []types.Relationship
		k.IterateRelationships(ctx, func(index int64, relationship types.Relationship) (stop bool) {
			if !k.HasProfile(ctx, relationship.Creator) || relationship.Creator == relationship.Recipient {
				invalidRelationships = append(invalidRelationships, relationship)
			}
			return false
		})
		broken := len(invalidRelationships) != 0
		return sdk.FormatInvariant(types.ModuleName, "invalid relationships",
			formatOutputRelationships(invalidRelationships)), broken
	}
}
--------------------------------------------------------------------------------------------------------------------
ValidRelationshipsInvariant checks that all relationships are associated with a creator that has a profile
and they do not have the same user as creator and recipient
package keeper
import (
	"fmt"
	sdk "github.com/cosmos/cosmos-sdk/types"
	"github.com/desmos-labs/desmos/v2/x/profiles/types"
)
func RegisterInvariants(ir sdk.InvariantRegistry, keeper Keeper) {
	ir.RegisterRoute(types.ModuleName, "valid-profiles", ValidProfilesInvariant(keeper))
	ir.RegisterRoute(types.ModuleName, "valid-user-blocks", ValidUserBlocksInvariant(keeper))
	ir.RegisterRoute(types.ModuleName, "valid-relationships", ValidRelationshipsInvariant(keeper))
	ir.RegisterRoute(types.ModuleName, "valid-dtag-transfer-requests", ValidDTagTransferRequests(keeper))
	ir.RegisterRoute(types.ModuleName, "valid-chain-links", ValidChainLinks(keeper))
	ir.RegisterRoute(types.ModuleName, "valid-application-links", ValidApplicationLinks(keeper))
}
func AllInvariants(k Keeper) sdk.Invariant {
	return func(ctx sdk.Context) (string, bool) {
		res, broken := ValidProfilesInvariant(k)(ctx)
		if broken {
			return res, broken
		}
		res, broken = ValidUserBlocksInvariant(k)(ctx)
		if broken {
			return res, broken
		}
		res, broken = ValidRelationshipsInvariant(k)(ctx)
		if broken {
			return res, broken
		}
		res, broken = ValidDTagTransferRequests(k)(ctx)
		if broken {
			return res, broken
		}
		res, broken = ValidChainLinks(k)(ctx)
		if broken {
			return res, broken
		}
		res, broken = ValidApplicationLinks(k)(ctx)
		if broken {
			return res, broken
		}
		return "Every invariant condition is fulfilled correctly", false
	}
}
func ValidProfilesInvariant(k Keeper) sdk.Invariant {
	return func(ctx sdk.Context) (string, bool) {
		var invalidProfiles []*types.Profile
		k.IterateProfiles(ctx, func(_ int64, profile *types.Profile) (stop bool) {
			if err := profile.Validate(); err != nil {
				invalidProfiles = append(invalidProfiles, profile)
			}
			return false
		})
		broken := len(invalidProfiles) != 0
		return sdk.FormatInvariant(types.ModuleName, "invalid profiles",
			formatOutputProfiles(invalidProfiles)), broken
	}
}
func formatOutputProfiles(invalidProfiles []*types.Profile) (outputProfiles string) {
	outputProfiles = "The following list contains invalid profiles:\n"
	for _, invalidProfile := range invalidProfiles {
		outputProfiles += fmt.Sprintf(
			"[DTag]: %s, [Creator]: %s\n",
			invalidProfile.DTag, invalidProfile.GetAddress().String(),
		)
	}
	return outputProfiles
}
func ValidUserBlocksInvariant(k Keeper) sdk.Invariant {
	return func(ctx sdk.Context) (string, bool) {
		var invalidBlocks []types.UserBlock
		k.IterateBlocks(ctx, func(index int64, block types.UserBlock) (stop bool) {
			if !k.HasProfile(ctx, block.Blocker) || block.Blocker == block.Blocked {
				invalidBlocks = append(invalidBlocks, block)
			}
			return false
		})
		broken := len(invalidBlocks) != 0
		return sdk.FormatInvariant(types.ModuleName, "invalid user blocks",
			formatOutputBlocks(invalidBlocks)), broken
	}
}
func formatOutputBlocks(invalidBlocks []types.UserBlock) (outputBlocks string) {
	outputBlocks = "The following list contains invalid user blocks:\n"
	for _, block := range invalidBlocks {
		outputBlocks += fmt.Sprintf(
			"[Blocker]: %s, [Blocked]: %s, [Subspace]: %s\n",
			block.Blocker, block.Blocked, block.Subspace,
		)
	}
	return outputBlocks
}