github.com/Finschia/finschia-sdk@v0.49.1/x/collection/genesis.go (about)

     1  package collection
     2  
     3  import (
     4  	codectypes "github.com/Finschia/finschia-sdk/codec/types"
     5  	sdk "github.com/Finschia/finschia-sdk/types"
     6  	sdkerrors "github.com/Finschia/finschia-sdk/types/errors"
     7  )
     8  
     9  const (
    10  	DefaultDepthLimit = 1
    11  	DefaultWidthLimit = 4
    12  )
    13  
    14  // ValidateGenesis check the given genesis state has no integrity issues
    15  func ValidateGenesis(data GenesisState) error {
    16  	if err := validateParams(data.Params); err != nil {
    17  		return err
    18  	}
    19  
    20  	for _, contract := range data.Contracts {
    21  		if err := ValidateContractID(contract.Id); err != nil {
    22  			return err
    23  		}
    24  
    25  		if err := validateName(contract.Name); err != nil {
    26  			return err
    27  		}
    28  		if err := validateURI(contract.Uri); err != nil {
    29  			return err
    30  		}
    31  		if err := validateMeta(contract.Meta); err != nil {
    32  			return err
    33  		}
    34  	}
    35  
    36  	for _, nextClassID := range data.NextClassIds {
    37  		if err := ValidateContractID(nextClassID.ContractId); err != nil {
    38  			return err
    39  		}
    40  	}
    41  
    42  	for _, contractClasses := range data.Classes {
    43  		if err := ValidateContractID(contractClasses.ContractId); err != nil {
    44  			return err
    45  		}
    46  
    47  		if len(contractClasses.Classes) == 0 {
    48  			return sdkerrors.ErrInvalidRequest.Wrap("classes cannot be empty")
    49  		}
    50  		for i := range contractClasses.Classes {
    51  			any := &contractClasses.Classes[i]
    52  			class := TokenClassFromAny(any)
    53  			if err := class.ValidateBasic(); err != nil {
    54  				return err
    55  			}
    56  		}
    57  	}
    58  
    59  	for _, contractNextTokenIDs := range data.NextTokenIds {
    60  		if err := ValidateContractID(contractNextTokenIDs.ContractId); err != nil {
    61  			return err
    62  		}
    63  
    64  		if len(contractNextTokenIDs.TokenIds) == 0 {
    65  			return sdkerrors.ErrInvalidRequest.Wrap("next token ids cannot be empty")
    66  		}
    67  		for _, nextTokenID := range contractNextTokenIDs.TokenIds {
    68  			if nextTokenID.Id.IsZero() {
    69  				return sdkerrors.ErrInvalidRequest.Wrap("nextTokenID.Id is not supposed to be zero")
    70  			}
    71  			if err := ValidateClassID(nextTokenID.ClassId); err != nil {
    72  				return err
    73  			}
    74  		}
    75  	}
    76  
    77  	for _, contractBalances := range data.Balances {
    78  		if err := ValidateContractID(contractBalances.ContractId); err != nil {
    79  			return err
    80  		}
    81  
    82  		if len(contractBalances.Balances) == 0 {
    83  			return sdkerrors.ErrInvalidRequest.Wrap("balances cannot be empty")
    84  		}
    85  		for _, balance := range contractBalances.Balances {
    86  			if _, err := sdk.AccAddressFromBech32(balance.Address); err != nil {
    87  				return err
    88  			}
    89  			if err := balance.Amount.ValidateBasic(); err != nil {
    90  				return err
    91  			}
    92  		}
    93  	}
    94  
    95  	for _, contractNFTs := range data.Nfts {
    96  		if err := ValidateContractID(contractNFTs.ContractId); err != nil {
    97  			return err
    98  		}
    99  
   100  		if len(contractNFTs.Nfts) == 0 {
   101  			return sdkerrors.ErrInvalidRequest.Wrap("nfts cannot be empty")
   102  		}
   103  		for _, token := range contractNFTs.Nfts {
   104  			if err := ValidateTokenID(token.TokenId); err != nil {
   105  				return err
   106  			}
   107  			if err := validateName(token.Name); err != nil {
   108  				return err
   109  			}
   110  			if err := validateMeta(token.Meta); err != nil {
   111  				return err
   112  			}
   113  		}
   114  	}
   115  
   116  	for _, contractParents := range data.Parents {
   117  		if err := ValidateContractID(contractParents.ContractId); err != nil {
   118  			return err
   119  		}
   120  
   121  		if len(contractParents.Relations) == 0 {
   122  			return sdkerrors.ErrInvalidRequest.Wrap("parents cannot be empty")
   123  		}
   124  		for _, relation := range contractParents.Relations {
   125  			if err := ValidateTokenID(relation.Self); err != nil {
   126  				return err
   127  			}
   128  			if err := ValidateTokenID(relation.Other); err != nil {
   129  				return err
   130  			}
   131  		}
   132  	}
   133  
   134  	for _, contractAuthorizations := range data.Authorizations {
   135  		if err := ValidateContractID(contractAuthorizations.ContractId); err != nil {
   136  			return err
   137  		}
   138  
   139  		if len(contractAuthorizations.Authorizations) == 0 {
   140  			return sdkerrors.ErrInvalidRequest.Wrap("authorizations cannot be empty")
   141  		}
   142  		for _, authorization := range contractAuthorizations.Authorizations {
   143  			if _, err := sdk.AccAddressFromBech32(authorization.Holder); err != nil {
   144  				return err
   145  			}
   146  			if _, err := sdk.AccAddressFromBech32(authorization.Operator); err != nil {
   147  				return err
   148  			}
   149  		}
   150  	}
   151  
   152  	for _, contractGrants := range data.Grants {
   153  		if err := ValidateContractID(contractGrants.ContractId); err != nil {
   154  			return err
   155  		}
   156  
   157  		if len(contractGrants.Grants) == 0 {
   158  			return sdkerrors.ErrInvalidRequest.Wrap("grants cannot be empty")
   159  		}
   160  		for _, grant := range contractGrants.Grants {
   161  			if _, err := sdk.AccAddressFromBech32(grant.Grantee); err != nil {
   162  				return err
   163  			}
   164  			if err := ValidatePermission(grant.Permission); err != nil {
   165  				return err
   166  			}
   167  		}
   168  	}
   169  
   170  	for _, contractSupplies := range data.Supplies {
   171  		if err := ValidateContractID(contractSupplies.ContractId); err != nil {
   172  			return err
   173  		}
   174  
   175  		if len(contractSupplies.Statistics) == 0 {
   176  			return sdkerrors.ErrInvalidRequest.Wrap("supplies cannot be empty")
   177  		}
   178  		for _, supply := range contractSupplies.Statistics {
   179  			if err := ValidateClassID(supply.ClassId); err != nil {
   180  				return err
   181  			}
   182  			if !supply.Amount.IsPositive() {
   183  				return sdkerrors.ErrInvalidRequest.Wrap("supply must be positive")
   184  			}
   185  		}
   186  	}
   187  
   188  	for _, contractBurnts := range data.Burnts {
   189  		if err := ValidateContractID(contractBurnts.ContractId); err != nil {
   190  			return err
   191  		}
   192  
   193  		if len(contractBurnts.Statistics) == 0 {
   194  			return sdkerrors.ErrInvalidRequest.Wrap("burnts cannot be empty")
   195  		}
   196  		for _, burnt := range contractBurnts.Statistics {
   197  			if err := ValidateClassID(burnt.ClassId); err != nil {
   198  				return err
   199  			}
   200  			if !burnt.Amount.IsPositive() {
   201  				return sdkerrors.ErrInvalidRequest.Wrap("burnt must be positive")
   202  			}
   203  		}
   204  	}
   205  
   206  	return nil
   207  }
   208  
   209  // DefaultGenesisState - Return a default genesis state
   210  func DefaultGenesisState() *GenesisState {
   211  	return &GenesisState{
   212  		Params: Params{
   213  			DepthLimit: DefaultDepthLimit,
   214  			WidthLimit: DefaultWidthLimit,
   215  		},
   216  	}
   217  }
   218  
   219  func (data GenesisState) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
   220  	for _, contractClasses := range data.Classes {
   221  		for i := range contractClasses.Classes {
   222  			any := &contractClasses.Classes[i]
   223  			if err := TokenClassUnpackInterfaces(any, unpacker); err != nil {
   224  				return err
   225  			}
   226  		}
   227  	}
   228  
   229  	return nil
   230  }